﻿using Engine;
using Engine.Audio;
using Engine.Graphics;
using Engine.Input;
using Engine.Media;
using Engine.Serialization;
using Game;
using GameEntitySystem;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using TemplatesDatabase;
using XmlUtilities;
using System.Threading.Tasks;

namespace CommandBlock
{
    public class SubsystemCommandDef : SubsystemCommand, IUpdateable, IDrawable
    {
        public SubsystemTerrain m_subsystemTerrain;

        public SubsystemBodies m_subsystemBodies;

        public SubsystemPickables m_subsystemPickables;

        public SubsystemBlockEntities m_subsystemBlockEntities;

        public SubsystemParticles m_subsystemParticles;

        public SubsystemMovingBlocks m_subsystemMovingBlocks;

        public SubsystemFurnitureBlockBehavior m_subsystemFurnitureBlockBehavior;

        public SubsystemGameInfo m_subsystemGameInfo;

        public SubsystemSky m_subsystemSky;

        public SubsystemAudio m_subsystemAudio;

        public SubsystemTime m_subsystemTime;

        public static Dictionary<Color, int> ColorIndexCaches = new Dictionary<Color, int>();

        public static Dictionary<Point3, Pattern> PatternPoints = new Dictionary<Point3, Pattern>();

        public static Dictionary<Point3, PatternFont> PatternFonts = new Dictionary<Point3, PatternFont>();

        public static Dictionary<int, float[]> OriginFirmBlockList = new Dictionary<int, float[]>();

        public static Dictionary<string, string> CreatureTextures = new Dictionary<string, string>();

        public static Dictionary<string, string> CreatureModels = new Dictionary<string, string>();

        public static Dictionary<string, ScreenPattern> ScreenPatterns = new Dictionary<string, ScreenPattern>();

        public static Dictionary<string, string> Notes = new Dictionary<string, string>();

        public static CommandMusic m_commandMusic;

        public List<int> m_firmBlockList = new List<int>();

        public bool m_firmAllBlocks = false;

        public static List<ComponentCreature> DeadCreatureList = new List<ComponentCreature>();

        public PrimitivesRenderer3D m_primitivesRenderer = new PrimitivesRenderer3D();

        public TexturedBatch3D[] m_batches = new TexturedBatch3D[2];

        public bool m_enterDeathScreen = false;

        public float m_aimDurationTime = 0;

        public float m_worldRunTime = 0;

        public bool m_shapeshifter;

        public string m_playerBoxStage;

        public Color m_rainColor;

        public Color m_skyColor;

        public bool m_onCapture = false;

        public Point2? m_eatItem;

        public CanvasWidget m_screenPatternsWidget;

        public ContainerWidget m_screenLabelCanvasWidget;

        public float m_screenLabelCloseTime;

        public List<BaseBatch> m_aimingSightsBatches;

        public static CopyBlockManager CopyBlockManager;

        public static bool DisplayColorBlock = false;

        public float m_recordTime = 0;

        public List<Point2> m_terrainChunks007 = new List<Point2>();

        public Dictionary<string, List<Point3>> m_waitingMoveSets = new Dictionary<string, List<Point3>>();

        public Dictionary<string, List<MovingEntityBlock>> m_movingEntityBlocks = new Dictionary<string, List<MovingEntityBlock>>();

        public static Dictionary<string, MovingCollision> m_movingCollisions = new Dictionary<string, MovingCollision>();

        public object m_interactResult;

        public bool m_interactTest;

        public float m_moveResetTime;

        public UpdateOrder UpdateOrder => UpdateOrder.Default;

        public int[] DrawOrders => new int[1] { 1000 };

        public void Update(float dt)
        {
            if (m_componentPlayer == null) return;
            if (m_enterDeathScreen) SetDeathScreen();
            if (m_componentPlayer.ComponentInput.PlayerInput.Aim.HasValue) m_aimDurationTime += dt;
            else m_aimDurationTime = 0;
            if (m_worldRunTime == 0)
            {
                Initialize();
            }
            m_worldRunTime += dt;
            if (m_moveResetTime > 0.5f)
            {
                m_moveResetTime = 0;
                m_movingCollisions.Clear();
            }
            m_moveResetTime += dt;
            if (m_screenLabelCloseTime > 0)
            {
                m_screenLabelCloseTime -= dt;
                if (m_screenLabelCloseTime < 0.1f)
                {
                    m_screenLabelCanvasWidget.IsVisible = false;
                    m_screenLabelCloseTime = 0;
                }
            }
            foreach (var w in ScreenPatterns.Values)
            {
                w.OutTime = MathUtils.Max(0, w.OutTime - dt);
                if (w.Widget is BitmapButtonWidget && ((ButtonWidget)w.Widget).IsClicked)
                {
                    w.OutTime = 0.1f;
                }
            }
            if (m_interactTest && m_componentPlayer.ComponentInput.PlayerInput.Interact.HasValue)
            {
                Ray3 ray = m_componentPlayer.ComponentInput.PlayerInput.Interact.Value;
                m_interactResult = DataHandle.Raycast(ray, m_componentPlayer.ComponentMiner);
            }
            else m_interactResult = null;
            m_recordTime += dt;
            if (RecordManager.Recording && m_recordTime >= RecordManager.FrameTime)
            {
                m_recordTime = 0;
                RecordManager.AddRecordPlayerStats(m_componentPlayer, (float)m_subsystemTime.GameTime);
            }
            if (RecordManager.Replaying && m_recordTime >= RecordManager.FrameTime)
            {
                m_recordTime = 0;
                RecordManager.Replay(m_componentPlayer, dt);
            }
        }

        public void Draw(Camera camera, int drawOrder)
        {
            DrawPatternPoints(camera, drawOrder);
        }

        public void Initialize()
        {
            LoadNotes();
            WithdrawBlockManager.Clear();
        }

        public override void Load(ValuesDictionary valuesDictionary)
        {
            base.Load(valuesDictionary);
            m_subsystemTerrain = base.Project.FindSubsystem<SubsystemTerrain>(true);
            m_subsystemBodies = base.Project.FindSubsystem<SubsystemBodies>(true);
            m_subsystemPickables = base.Project.FindSubsystem<SubsystemPickables>(true);
            m_subsystemBlockEntities = base.Project.FindSubsystem<SubsystemBlockEntities>(true);
            m_subsystemParticles = base.Project.FindSubsystem<SubsystemParticles>(true);
            m_subsystemMovingBlocks = base.Project.FindSubsystem<SubsystemMovingBlocks>(true);
            m_subsystemFurnitureBlockBehavior = base.Project.FindSubsystem<SubsystemFurnitureBlockBehavior>(true);
            m_subsystemGameInfo = base.Project.FindSubsystem<SubsystemGameInfo>(true);
            m_subsystemSky = base.Project.FindSubsystem<SubsystemSky>(true);
            m_subsystemAudio = base.Project.FindSubsystem<SubsystemAudio>(true);
            m_subsystemTime = base.Project.FindSubsystem<SubsystemTime>(true);
            m_aimDurationTime = 0;
            m_worldRunTime = 0;
            m_screenLabelCloseTime = 0;
            m_moveResetTime = 0;
            m_shapeshifter = valuesDictionary.GetValue<bool>("Shapeshifter");
            m_playerBoxStage = valuesDictionary.GetValue<string>("PlayerBoxStage");
            m_commandMusic = new CommandMusic(valuesDictionary.GetValue<string>("CommandMusic"), null);
            string firmBlockLine = valuesDictionary.GetValue<string>("FirmBlocks");
            if (!string.IsNullOrEmpty(firmBlockLine))
            {
                m_firmBlockList.Clear();
                foreach (string sid in firmBlockLine.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    m_firmBlockList.Add(int.Parse(sid));
                }
            }
            if (SubsystemCommandExt.LoadAction == null)
            {
                SubsystemCommandExt.LoadAction += delegate
                {
                    foreach (int id in m_firmBlockList) SetFirmBlocks(id, true, null);
                };
            }
            m_interactTest = false;
            base.Project.FindSubsystem<SubsystemCommandBlockBehavior>().OnCommandBlockGenerated += delegate (CommandData commandData)
            {
                if (commandData.Name == "clickinteract")
                {
                    m_interactTest = true;
                }
            };
            m_rainColor = valuesDictionary.GetValue<Color>("RainColor");
            m_skyColor = valuesDictionary.GetValue<Color>("SkyColor");
            DeadCreatureList.Clear();
            ColorIndexCaches.Clear();
            ScreenPatterns.Clear();
            LoadChunks007(valuesDictionary);
            LoadCreatureTextureOrModels(valuesDictionary);
            LoadPatternPoints(valuesDictionary);
            LoadWaitMoveSet(valuesDictionary);
            LoadMoveEntityBlocks(valuesDictionary);
            MoveBlockCollidedAction();
            Function();
            Condition();
        }

        public override void Save(ValuesDictionary valuesDictionary)
        {
            base.Save(valuesDictionary);
            valuesDictionary.SetValue("Shapeshifter", m_shapeshifter);
            valuesDictionary.SetValue("PlayerBoxStage", m_playerBoxStage);
            valuesDictionary.SetValue("CommandMusic", m_commandMusic.Name);
            string firmBlockLine = string.Empty;
            foreach (int id in m_firmBlockList) firmBlockLine += id + ",";
            valuesDictionary.SetValue("FirmBlocks", firmBlockLine);
            valuesDictionary.SetValue("RainColor", m_rainColor);
            valuesDictionary.SetValue("SkyColor", m_skyColor);
            SaveChunks007(valuesDictionary);
            SaveCreatureTextureOrModels(valuesDictionary);
            SavePatternPoints(valuesDictionary);
            SaveWaitMoveSet(valuesDictionary);
            SaveMoveEntityBlocks(valuesDictionary);
        }

        public override void OnEntityAdded(Entity entity)
        {
            base.OnEntityAdded(entity);
            if (m_shapeshifter) SetShapeshifter(entity);
            if (CreatureTextures.Count > 0 || CreatureModels.Count > 0)
            {
                SetCreatureTextureOrModels(entity);
            }
            if (entity.FindComponent<ComponentPlayer>() != null)
            {
                SetPlayerBoxStage(m_playerBoxStage);
                InitScreenLabelCanvas();
            }
            //MoveBlockCollidedEntity(entity);
        }

        public override void Dispose()
        {
            base.Dispose();
            SaveNotes();
            if (m_commandMusic != null && m_commandMusic.Sound != null)
            {
                m_commandMusic.Sound.Dispose();
            }
        }

        public void Function()
        {
            AddFunction("book", delegate (CommandData commandData)          //命令手册
            {
                if (commandData.DIYPara.TryGetValue("BufferTime", out object value))
                {
                    if (m_subsystemTime.GameTime - (double)value < 3f)
                    {
                        ShowSubmitTips("你已经看过了，歇2秒再看吧");
                        return SubmitResult.Fail;
                    }
                }
                commandData.DIYPara["BufferTime"] = m_subsystemTime.GameTime;
                m_componentPlayer.ComponentGui.ModalPanelWidget = new ManualTopicWidget(m_componentPlayer, 0);
                CommandEditWidget.GuiWidgetControl(m_componentPlayer, true);
                return SubmitResult.Success;
            });
            AddFunction("message", delegate (CommandData commandData)       //显示信息
            {
                //message type:default text:hello[n]command color:255,0,0,255 con:true
                if (commandData.Type == "default")
                {
                    string text = (string)commandData.GetValue("text");
                    Color color = (Color)commandData.GetValue("color");
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.ComponentGui.DisplaySmallMessage(text, color, true, con);
                }
                //message type:float text1:hello[e]command text2:author[c]再回首zh
                else if (commandData.Type == "float")
                {
                    string text1 = (string)commandData.GetValue("text1");
                    string text2 = (string)commandData.GetValue("text2");
                    m_componentPlayer.ComponentGui.DisplayLargeMessage(text1, text2, 3f, 0f);
                }
                return SubmitResult.Success;
            });
            AddFunction("place", delegate (CommandData commandData)         //放置方块
            {
                WithdrawBlockManager wbManager = null;
                if (WithdrawBlockManager.WithdrawMode) wbManager = new WithdrawBlockManager();
                //place type:default pos:3,3,3 id:46 @C
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    ChangeBlockValue(wbManager, pos.X, pos.Y, pos.Z, id, false);
                    PlaceReprocess(wbManager, commandData, false, pos, pos);
                }
                //place type:line pos1:3,3,3 pos2:5,5,5 id:46 @C
                else if (commandData.Type == "line")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    int m = MathUtils.Max(MathUtils.Max(cube.LengthX, cube.LengthY), cube.LengthZ);
                    for (int j = 0; j <= m; j++)
                    {
                        int x = arpos[0].X + (int)MathUtils.Round((float)j / (float)m * (float)(arpos[1].X - arpos[0].X));
                        int y = arpos[0].Y + (int)MathUtils.Round((float)j / (float)m * (float)(arpos[1].Y - arpos[0].Y));
                        int z = arpos[0].Z + (int)MathUtils.Round((float)j / (float)m * (float)(arpos[1].Z - arpos[0].Z));
                        ChangeBlockValue(wbManager, x, y, z, id, false);
                    }
                    PlaceReprocess(wbManager, commandData, false, cube.MinPoint, cube.MaxPoint);
                }
                //place type:frame pos1:3,3,3 pos2:5,5,5 id:46
                else if (commandData.Type == "frame")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    for (int l = 0; l < cube.LengthX; l++)
                    {
                        ChangeBlockValue(wbManager, cube.MinPoint.X + l, cube.MinPoint.Y, cube.MinPoint.Z, id, false);
                        ChangeBlockValue(wbManager, cube.MinPoint.X + l, cube.MaxPoint.Y, cube.MinPoint.Z, id, false);
                        ChangeBlockValue(wbManager, cube.MinPoint.X + l, cube.MinPoint.Y, cube.MaxPoint.Z, id, false);
                        ChangeBlockValue(wbManager, cube.MinPoint.X + l, cube.MaxPoint.Y, cube.MaxPoint.Z, id, false);
                    }
                    for (int l = 0; l < cube.LengthY; l++)
                    {
                        ChangeBlockValue(wbManager, cube.MinPoint.X, cube.MinPoint.Y + l, cube.MinPoint.Z, id, false);
                        ChangeBlockValue(wbManager, cube.MaxPoint.X, cube.MinPoint.Y + l, cube.MinPoint.Z, id, false);
                        ChangeBlockValue(wbManager, cube.MinPoint.X, cube.MinPoint.Y + l, cube.MaxPoint.Z, id, false);
                        ChangeBlockValue(wbManager, cube.MaxPoint.X, cube.MinPoint.Y + l, cube.MaxPoint.Z, id, false);
                    }
                    for (int l = 0; l < cube.LengthZ; l++)
                    {
                        ChangeBlockValue(wbManager, cube.MinPoint.X, cube.MinPoint.Y, cube.MinPoint.Z + l, id, false);
                        ChangeBlockValue(wbManager, cube.MaxPoint.X, cube.MinPoint.Y, cube.MinPoint.Z + l, id, false);
                        ChangeBlockValue(wbManager, cube.MinPoint.X, cube.MaxPoint.Y, cube.MinPoint.Z + l, id, false);
                        ChangeBlockValue(wbManager, cube.MaxPoint.X, cube.MaxPoint.Y, cube.MinPoint.Z + l, id, false);
                    }
                    PlaceReprocess(wbManager, commandData, false, cube.MinPoint, cube.MaxPoint);
                }
                //place type:triangle pos1:0,0,0 pos2:1,1,1 pos3:1,1,1 id:46
                else if (commandData.Type == "triangle")
                {
                    Point3 pos1 = GetOnePoint("pos1", commandData);
                    Point3 pos2 = GetOnePoint("pos2", commandData);
                    Point3 pos3 = GetOnePoint("pos3", commandData);
                    int id = (int)commandData.GetValue("id");
                    Point3[] arpos = new Point3[3];
                    for (int i = 0; i < 3; i++)
                    {
                        switch (i)
                        {
                            case 0: arpos = new Point3[3] { pos1, pos2, pos3 }; break;
                            case 1: arpos = new Point3[3] { pos1, pos3, pos2 }; break;
                            case 2: arpos = new Point3[3] { pos2, pos3, pos1 }; break;
                        }
                        List<Point3> list = new List<Point3>();
                        CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                        int m = MathUtils.Max(MathUtils.Max(cube.LengthX, cube.LengthY), cube.LengthZ);
                        for (int j = 0; j <= m; j++)
                        {
                            int x = arpos[0].X + (int)MathUtils.Round((float)j / (float)m * (float)(arpos[1].X - arpos[0].X));
                            int y = arpos[0].Y + (int)MathUtils.Round((float)j / (float)m * (float)(arpos[1].Y - arpos[0].Y));
                            int z = arpos[0].Z + (int)MathUtils.Round((float)j / (float)m * (float)(arpos[1].Z - arpos[0].Z));
                            list.Add(new Point3(x, y, z));
                            ChangeBlockValue(wbManager, x, y, z, id);
                        }
                        foreach (Point3 p in list)
                        {
                            CubeArea cube2 = new CubeArea(arpos[2], p);
                            int m2 = MathUtils.Max(MathUtils.Max(cube2.LengthX, cube2.LengthY), cube2.LengthZ);
                            for (int j = 0; j <= m2; j++)
                            {
                                int x = arpos[2].X + (int)MathUtils.Round((float)j / (float)m2 * (float)(p.X - arpos[2].X));
                                int y = arpos[2].Y + (int)MathUtils.Round((float)j / (float)m2 * (float)(p.Y - arpos[2].Y));
                                int z = arpos[2].Z + (int)MathUtils.Round((float)j / (float)m2 * (float)(p.Z - arpos[2].Z));
                                ChangeBlockValue(wbManager, x, y, z, id);
                            }
                        }
                    }
                    CubeArea cube3 = new CubeArea(pos1, pos2);
                    int max_X = MathUtils.Max(pos3.X, cube3.MaxPoint.X);
                    int max_Y = MathUtils.Max(pos3.Y, cube3.MaxPoint.Y);
                    int max_Z = MathUtils.Max(pos3.Z, cube3.MaxPoint.Z);
                    int min_X = MathUtils.Min(pos3.X, cube3.MinPoint.X);
                    int min_Y = MathUtils.Min(pos3.Y, cube3.MinPoint.Y);
                    int min_Z = MathUtils.Min(pos3.Z, cube3.MinPoint.Z);
                    PlaceReprocess(wbManager, commandData, true, new Point3(min_X, min_Y, min_Z), new Point3(max_X, max_Y, max_Z));
                }
                //place type:cube pos1:3,3,3 pos2:5,5,5 id:46 con:false
                else if (commandData.Type == "cube")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    bool con = (bool)commandData.GetValue("con");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    CubeArea cube2 = new CubeArea(cube.MinPoint + Point3.One, cube.MaxPoint - Point3.One);
                    cube.Ergodic(delegate
                    {
                        if (con)
                        {
                            if (!cube2.Exist(cube.Current))
                            {
                                ChangeBlockValue(wbManager, cube.Current.X, cube.Current.Y, cube.Current.Z, id);
                            }
                        }
                        else
                        {
                            ChangeBlockValue(wbManager, cube.Current.X, cube.Current.Y, cube.Current.Z, id);
                        }
                        return false;
                    });
                    PlaceReprocess(wbManager, commandData, true, cube.MinPoint, cube.MaxPoint);
                }
                //place type:sphere pos:50,50,50 id:46 r:20 con:false
                else if (commandData.Type == "sphere")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    int r = (int)commandData.GetValue("r");
                    bool con = (bool)commandData.GetValue("con");
                    SphereArea sphere = new SphereArea(r, pos);
                    SphereArea sphere2 = new SphereArea(r - 1, pos);
                    sphere.Ergodic(delegate
                    {
                        if (con)
                        {
                            if (!sphere2.Exist(sphere.Current))
                            {
                                ChangeBlockValue(wbManager, sphere.Current.X, sphere.Current.Y, sphere.Current.Z, id);
                            }
                        }
                        else
                        {
                            ChangeBlockValue(wbManager, sphere.Current.X, sphere.Current.Y, sphere.Current.Z, id);
                        }
                    });
                    PlaceReprocess(wbManager, commandData, true, sphere.MinPoint, sphere.MaxPoint);
                }
                //place type:column pos:50,50,50 id:46 r:20 h:30 opt:+x con:true
                else if (commandData.Type == "column")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    int r = (int)commandData.GetValue("r");
                    int h = (int)commandData.GetValue("h");
                    string opt = (string)commandData.GetValue("opt");
                    bool con = (bool)commandData.GetValue("con");
                    CoordDirection coord = CoordDirection.PY;
                    Point3 p = Point3.Zero;
                    switch (opt)
                    {
                        case "+x": coord = CoordDirection.PX; p = new Point3(1, 0, 0); break;
                        case "+y": coord = CoordDirection.PY; p = new Point3(0, 1, 0); break;
                        case "+z": coord = CoordDirection.PZ; p = new Point3(0, 0, 1); break;
                        case "-x": coord = CoordDirection.NX; p = new Point3(-1, 0, 0); break;
                        case "-y": coord = CoordDirection.NY; p = new Point3(0, -1, 0); break;
                        case "-z": coord = CoordDirection.NZ; p = new Point3(0, 0, -1); break;
                    }
                    ColumnArea column = new ColumnArea(r, h, pos, coord);
                    ColumnArea column2 = new ColumnArea(r - 1, h - 2, pos + p, coord);
                    column.Ergodic(delegate
                    {
                        if (con)
                        {
                            if (!column2.Exist(column.Current))
                            {
                                ChangeBlockValue(wbManager, column.Current.X, column.Current.Y, column.Current.Z, id);
                            }
                        }
                        else
                        {
                            ChangeBlockValue(wbManager, column.Current.X, column.Current.Y, column.Current.Z, id);
                        }
                    });
                    PlaceReprocess(wbManager, commandData, true, column.MinPoint, column.MaxPoint);
                }
                //place type:cone pos:50,50,50 id:46 r:20 h:30 opt:+y con:true
                else if (commandData.Type == "cone")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    int r = (int)commandData.GetValue("r");
                    int h = (int)commandData.GetValue("h");
                    string opt = (string)commandData.GetValue("opt");
                    bool con = (bool)commandData.GetValue("con");
                    CoordDirection coord = CoordDirection.PY;
                    Point3 p = Point3.Zero;
                    switch (opt)
                    {
                        case "+x": coord = CoordDirection.PX; p = new Point3(1, 0, 0); break;
                        case "+y": coord = CoordDirection.PY; p = new Point3(0, 1, 0); break;
                        case "+z": coord = CoordDirection.PZ; p = new Point3(0, 0, 1); break;
                        case "-x": coord = CoordDirection.NX; p = new Point3(-1, 0, 0); break;
                        case "-y": coord = CoordDirection.NY; p = new Point3(0, -1, 0); break;
                        case "-z": coord = CoordDirection.NZ; p = new Point3(0, 0, -1); break;
                    }
                    ConeArea cone = new ConeArea(r, h, pos, coord);
                    ConeArea cone2 = new ConeArea((int)(0.8f * (float)r), h - 2, pos + p, coord);
                    cone.Ergodic(delegate
                    {
                        if (con)
                        {
                            if (!cone2.Exist(cone.Current))
                            {
                                ChangeBlockValue(wbManager, cone.Current.X, cone.Current.Y, cone.Current.Z, id);
                            }
                        }
                        else
                        {
                            ChangeBlockValue(wbManager, cone.Current.X, cone.Current.Y, cone.Current.Z, id);
                        }
                    });
                    PlaceReprocess(wbManager, commandData, true, cone.MinPoint, cone.MaxPoint);
                }
                //place type:function pos:0,0,0 id:46 int:v func1:x+y<z func2:null limx:0,1 limy:0,1 limz:0,1
                else if (commandData.Type == "function")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    int v = (int)commandData.GetValue("v");
                    string func1 = (string)commandData.GetValue("func1");
                    string func2 = (string)commandData.GetValue("func2");
                    string limx = (string)commandData.GetValue("limx");
                    string limy = (string)commandData.GetValue("limy");
                    string limz = (string)commandData.GetValue("limz");
                    bool funcPass1 = (func1 == "null");
                    bool funcPass2 = (func2 == "null");
                    string[] funcArray1 = new string[3];
                    string[] funcArray2 = new string[3];
                    if (!funcPass1)
                    {
                        func1 = func1.Replace(" ", "");
                        if (func1.Contains(">"))
                        {
                            funcArray1[0] = func1.Split(new char[1] { '>' })[0];
                            funcArray1[1] = func1.Split(new char[1] { '>' })[1];
                            funcArray1[2] = ">";
                        }
                        else if (func1.Contains("<"))
                        {
                            funcArray1[0] = func1.Split(new char[1] { '<' })[0];
                            funcArray1[1] = func1.Split(new char[1] { '<' })[1];
                            funcArray1[2] = "<";
                        }
                        else if (func1.Contains("="))
                        {
                            funcArray1[0] = func1.Split(new char[1] { '=' })[0];
                            funcArray1[1] = func1.Split(new char[1] { '=' })[1];
                            funcArray1[2] = "=";
                        }
                        else
                        {
                            ShowSubmitTips("表达式有且只能包括'>','<','='其中一个符号");
                            return SubmitResult.Fail;
                        }
                    }
                    if (!funcPass2)
                    {
                        func2 = func2.Replace(" ", "");
                        if (func2.Contains(">"))
                        {
                            funcArray2[0] = func2.Split(new char[1] { '>' })[0];
                            funcArray2[1] = func2.Split(new char[1] { '>' })[1];
                            funcArray2[2] = ">";
                        }
                        else if (func2.Contains("<"))
                        {
                            funcArray2[0] = func2.Split(new char[1] { '<' })[0];
                            funcArray2[1] = func2.Split(new char[1] { '<' })[1];
                            funcArray2[2] = "<";
                        }
                        else if (func2.Contains("="))
                        {
                            funcArray2[0] = func2.Split(new char[1] { '=' })[0];
                            funcArray2[1] = func2.Split(new char[1] { '=' })[1];
                            funcArray2[2] = "=";
                        }
                        else
                        {
                            ShowSubmitTips("表达式有且只能包括'>','<','='其中一个符号");
                            return SubmitResult.Fail;
                        }
                    }
                    Point2 vx = DataHandle.GetPoint2Value(limx);
                    Point2 vy = DataHandle.GetPoint2Value(limy);
                    Point2 vz = DataHandle.GetPoint2Value(limz);
                    CubeArea cube = new CubeArea(new Point3(vx.X, vy.X, vz.X), new Point3(vx.Y, vy.Y, vz.Y));
                    Task.Run(delegate
                    {
                        try
                        {
                            int count = 0;
                            int eh = (int)(cube.LengthX * cube.LengthY * cube.LengthZ / 10f) + 1;
                            ShowSubmitTips(string.Format("{0}&{1}\n正在计算生成中,请等待片刻！", func1, func2));
                            cube.Ergodic(delegate
                            {
                                count++;
                                if (count % eh == 0)
                                {
                                    ShowSubmitTips(string.Format("{0}&{1}\n方块生成进度:{2}%", func1, func2, (int)(count / eh * 10f)));
                                }
                                bool pass1 = funcPass1;
                                bool pass2 = funcPass2;
                                if (!funcPass1)
                                {
                                    ExpressionCalculator expressionCalculator = new ExpressionCalculator(funcArray1[0]);
                                    ExpressionCalculator expressionCalculator2 = new ExpressionCalculator(funcArray1[1]);
                                    int left = expressionCalculator.Calculate(cube.Current.X, cube.Current.Y, cube.Current.Z);
                                    int right = expressionCalculator2.Calculate(cube.Current.X, cube.Current.Y, cube.Current.Z);
                                    switch (funcArray1[2])
                                    {
                                        case "<": pass1 = left < right; break;
                                        case ">": pass1 = left > right; break;
                                        case "=": pass1 = MathUtils.Abs(left - right) <= v; break;
                                    }
                                    if (left == int.MinValue || right == int.MinValue)
                                    {
                                        pass1 = false;
                                    }
                                }
                                if (!funcPass2)
                                {
                                    ExpressionCalculator expressionCalculator = new ExpressionCalculator(funcArray2[0]);
                                    ExpressionCalculator expressionCalculator2 = new ExpressionCalculator(funcArray2[1]);
                                    int left = expressionCalculator.Calculate(cube.Current.X, cube.Current.Y, cube.Current.Z);
                                    int right = expressionCalculator2.Calculate(cube.Current.X, cube.Current.Y, cube.Current.Z);
                                    switch (funcArray2[2])
                                    {
                                        case "<": pass2 = left < right; break;
                                        case ">": pass2 = left > right; break;
                                        case "=": pass2 = MathUtils.Abs(left - right) <= v; break;
                                    }
                                    if (left == int.MinValue || right == int.MinValue)
                                    {
                                        pass2 = false;
                                    }
                                }
                                if (pass1 && pass2)
                                {
                                    Point3 point = pos + cube.Current - cube.MinPoint;
                                    ChangeBlockValue(wbManager, point.X, point.Y, point.Z, id);
                                }
                                return false;
                            });
                            PlaceReprocess(wbManager, commandData, true, pos, pos + cube.MaxPoint - cube.MinPoint);
                            ShowSubmitTips(string.Format("{0}&{1}\n生成方块完成！", func1, func2));
                        }
                        catch (Exception e)
                        {
                            Log.Warning(string.Format("{0}&{1}:{2}", func1, func2, e.Message));
                            ShowSubmitTips(string.Format("{0}&{1}\n生成方块失败！请检查表达式以及定义域", func1, func2));
                        }
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("dig", delegate (CommandData commandData)           //挖掘方块
            {
                //dig type:default pos:3,3,3 @C
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    m_subsystemTerrain.DestroyCell(1, pos.X, pos.Y, pos.Z, 0, false, false);
                }
                //dig type:area pos1:3,3,3 pos2:5,5,5 @C
                else if (commandData.Type == "area")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    cube.Ergodic(delegate
                    {
                        m_subsystemTerrain.DestroyCell(1, cube.Current.X, cube.Current.Y, cube.Current.Z, 0, false, false);
                        return false;
                    });
                }
                //dig type:limit pos1:3,3,3 pos2:5,5,5 id:46 @C
                else if (commandData.Type == "limit")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    cube.Ergodic(delegate
                    {
                        int limitValue = GetLimitValue(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        if (limitValue == id)
                        {
                            m_subsystemTerrain.DestroyCell(1, cube.Current.X, cube.Current.Y, cube.Current.Z, 0, false, false);
                        }
                        return false;
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("replace", delegate (CommandData commandData)       //填充替换方块
            {
                WithdrawBlockManager wbManager = null;
                if (WithdrawBlockManager.WithdrawMode) wbManager = new WithdrawBlockManager();
                //replace type:default pos1:3,3,3 pos2:5,5,5 id1:46 id2:126
                if (commandData.Type == "default")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id1 = (int)commandData.GetValue("id1");
                    int id2 = (int)commandData.GetValue("id2");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    cube.Ergodic(delegate
                    {
                        int limitValue = GetLimitValue(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        if (limitValue == id1)
                        {
                            ChangeBlockValue(wbManager, cube.Current.X, cube.Current.Y, cube.Current.Z, id2);
                        }
                        return false;
                    });
                    PlaceReprocess(wbManager, commandData, true, cube.MinPoint, cube.MaxPoint);
                }
                //replace type:fuzzycolor pos1:3,3,3 pos2:5,5,5
                else if (commandData.Type == "fuzzycolor")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    cube.Ergodic(delegate
                    {
                        int limitValue = GetLimitValue(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        if (Terrain.ExtractContents(limitValue) == 72)
                        {
                            Color color = Command.ClayBlock.GetCommandColor(Terrain.ExtractData(limitValue));
                            if (!Command.ClayBlock.IsDefaultColor(color))
                            {
                                int clayValue = DataHandle.GetColorIndex(color) * 32768 + 16456;
                                ChangeBlockValue(wbManager, cube.Current.X, cube.Current.Y, cube.Current.Z, clayValue);
                            }
                        }
                        return false;
                    });
                    PlaceReprocess(wbManager, commandData, true, cube.MinPoint, cube.MaxPoint);
                }
                //replace type:padding pos1:3,3,3 pos2:5,5,5 id:46 opt:+x
                else if (commandData.Type == "padding")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    string opt = (string)commandData.GetValue("opt");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    if (opt == "+x" || opt == "-x")
                    {
                        for (int y = 0; y < cube.LengthY; y++)
                        {
                            for (int z = 0; z < cube.LengthZ; z++)
                            {
                                if (opt == "+x")
                                {
                                    for (int x = 0; x < cube.LengthX; x++)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0) break;
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, id);
                                    }
                                }
                                else
                                {
                                    for (int x = cube.LengthX - 1; x > 0; x--)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0) break;
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, id);
                                    }
                                }
                            }
                        }
                    }
                    else if (opt == "+y" || opt == "-y")
                    {
                        for (int x = 0; x < cube.LengthX; x++)
                        {
                            for (int z = 0; z < cube.LengthZ; z++)
                            {
                                if (opt == "+y")
                                {
                                    for (int y = 0; y < cube.LengthY; y++)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0) break;
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, id);
                                    }
                                }
                                else
                                {
                                    for (int y = cube.LengthY - 1; y > 0; y--)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0) break;
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, id);
                                    }
                                }
                            }
                        }
                    }
                    else if (opt == "+z" || opt == "-z")
                    {
                        for (int x = 0; x < cube.LengthX; x++)
                        {
                            for (int y = 0; y < cube.LengthY; y++)
                            {
                                if (opt == "+z")
                                {
                                    for (int z = 0; z < cube.LengthZ; z++)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0) break;
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, id);
                                    }
                                }
                                else
                                {
                                    for (int z = cube.LengthZ - 1; z > 0; z--)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0) break;
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, id);
                                    }
                                }
                            }
                        }
                    }
                    PlaceReprocess(wbManager, commandData, true, cube.MinPoint, cube.MaxPoint);
                }
                //replace type:overlay pos1:0,0,0 pos2:1,1,1 id:46 opt:+x con1:false con2:false
                else if (commandData.Type == "overlay")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    string opt = (string)commandData.GetValue("opt");
                    bool con1 = (bool)commandData.GetValue("con1");
                    bool con2 = (bool)commandData.GetValue("con2");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    bool pass = true;
                    if (opt == "+x" || opt == "-x")
                    {
                        for (int y = 0; y < cube.LengthY; y++)
                        {
                            for (int z = 0; z < cube.LengthZ; z++)
                            {
                                pass = true;
                                if (opt == "+x")
                                {
                                    for (int x = 0; x < cube.LengthX; x++)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0)
                                        {
                                            if (pass) ChangeBlockValue(wbManager, con2 ? p.X : p.X - 1, p.Y, p.Z, id);
                                            if (!con1) break;
                                            pass = false;
                                        }
                                        else pass = true;
                                    }
                                }
                                else
                                {
                                    for (int x = cube.LengthX - 1; x > 0; x--)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0)
                                        {
                                            if (pass) ChangeBlockValue(wbManager, con2 ? p.X : p.X + 1, p.Y, p.Z, id);
                                            if (!con1) break;
                                            pass = false;
                                        }
                                        else pass = true;
                                    }
                                }
                            }
                        }
                    }
                    else if (opt == "+y" || opt == "-y")
                    {
                        for (int x = 0; x < cube.LengthX; x++)
                        {
                            for (int z = 0; z < cube.LengthZ; z++)
                            {
                                pass = true;
                                if (opt == "+y")
                                {
                                    for (int y = 0; y < cube.LengthY; y++)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0)
                                        {
                                            if (pass) ChangeBlockValue(wbManager, p.X, con2 ? p.Y : p.Y - 1, p.Z, id);
                                            if (!con1) break;
                                            pass = false;
                                        }
                                        else pass = true;
                                    }
                                }
                                else
                                {
                                    for (int y = cube.LengthY - 1; y > 0; y--)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0)
                                        {
                                            if (pass) ChangeBlockValue(wbManager, p.X, con2 ? p.Y : p.Y + 1, p.Z, id);
                                            if (!con1) break;
                                            pass = false;
                                        }
                                        else pass = true;
                                    }
                                }
                            }
                        }
                    }
                    else if (opt == "+z" || opt == "-z")
                    {
                        for (int x = 0; x < cube.LengthX; x++)
                        {
                            for (int y = 0; y < cube.LengthY; y++)
                            {
                                pass = true;
                                if (opt == "+z")
                                {
                                    for (int z = 0; z < cube.LengthZ; z++)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0)
                                        {
                                            if (pass) ChangeBlockValue(wbManager, p.X, p.Y, con2 ? p.Z : p.Z - 1, id);
                                            if (!con1) break;
                                            pass = false;
                                        }
                                        else pass = true;
                                    }
                                }
                                else
                                {
                                    for (int z = cube.LengthZ - 1; z > 0; z--)
                                    {
                                        Point3 p = new Point3(x + cube.MinPoint.X, y + cube.MinPoint.Y, z + cube.MinPoint.Z);
                                        if (m_subsystemTerrain.Terrain.GetCellContents(p.X, p.Y, p.Z) != 0)
                                        {
                                            if (pass) ChangeBlockValue(wbManager, p.X, p.Y, con2 ? p.Z : p.Z + 1, id);
                                            if (!con1) break;
                                            pass = false;
                                        }
                                        else pass = true;
                                    }
                                }
                            }
                        }
                    }
                    PlaceReprocess(wbManager, commandData, true, cube.MinPoint, cube.MaxPoint);
                }
                return SubmitResult.Success;
            });
            AddFunction("addnpc", delegate (CommandData commandData)        //添加生物
            {
                //addnpc type:default pos:3,3,3 obj:tiger @C
                Point3 pos = GetOnePoint("pos", commandData);
                string obj = (string)commandData.GetValue("obj");
                string entityName = EntityInfoManager.GetEntityName(obj);
                if (entityName == "MalePlayer")
                {
                    ShowSubmitTips("不能添加玩家");
                    return SubmitResult.Fail;
                }
                Entity entity = DatabaseManager.CreateEntity(Project, entityName, true);
                ComponentFrame componentFrame = entity.FindComponent<ComponentFrame>();
                ComponentSpawn componentSpawn = entity.FindComponent<ComponentSpawn>();
                if (componentFrame != null && componentSpawn != null)
                {
                    componentFrame.Position = new Vector3(pos) + new Vector3(0.5f, 0f, 0.5f);
                    componentFrame.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, (new Random()).Float(0f, (float)MathUtils.PI * 2f));
                    componentSpawn.SpawnDuration = 0f;
                    Project.AddEntity(entity);
                }
                return SubmitResult.Success;
            });
            AddFunction("removenpc", delegate (CommandData commandData)     //移除生物
            {
                //removenpc type:default obj:tiger
                if (commandData.Type == "default")
                {
                    string obj = (string)commandData.GetValue("obj");
                    if (obj == "player")
                    {
                        ShowSubmitTips("不能移除玩家");
                        return SubmitResult.Fail;
                    }
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        Project.RemoveEntity(body.Entity, true);
                        return false;
                    });
                }
                //removenpc type:all
                else if (commandData.Type == "all")
                {
                    ErgodicBody("npc", delegate (ComponentBody body)
                    {
                        Project.RemoveEntity(body.Entity, true);
                        return false;
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("injure", delegate (CommandData commandData)        //伤害生物
            {
                //injure type:default obj:player v:10
                string obj = (string)commandData.GetValue("obj");
                int v = (int)commandData.GetValue("v");
                float amount = (float)v / 100f;
                ErgodicBody(obj, delegate (ComponentBody body)
                {
                    ComponentCreature creature = body.Entity.FindComponent<ComponentCreature>();
                    ComponentDamage damage = body.Entity.FindComponent<ComponentDamage>();
                    if (creature != null)
                    {
                        creature.ComponentHealth.Injure(amount, null, true, "不知道谁输的指令");
                    }
                    if (damage != null)
                    {
                        damage.Damage(amount);
                    }
                    return false;
                });
                return SubmitResult.Success;
            });
            AddFunction("kill", delegate (CommandData commandData)          //杀死生物
            {
                //kill type:default obj:tiger
                string obj = (string)commandData.GetValue("obj");
                commandData.Data.Add("v", 100);
                CommandData commandData2 = new CommandData(commandData.Position, commandData.Line);
                commandData2.Type = "default";
                commandData2.Data["obj"] = obj;
                commandData2.Data["v"] = 100;
                return Submit("injure", commandData2, false);
            });
            AddFunction("heal", delegate (CommandData commandData)          //回复生物血量
            {
                //heal type:default obj:player v:10
                string obj = (string)commandData.GetValue("obj");
                int v = (int)commandData.GetValue("v");
                float amount = (float)v / 100f;
                ErgodicBody(obj, delegate (ComponentBody body)
                {
                    ComponentCreature creature = body.Entity.FindComponent<ComponentCreature>();
                    ComponentDamage damage = body.Entity.FindComponent<ComponentDamage>();
                    if (creature != null)
                    {
                        creature.ComponentHealth.Heal(amount);
                    }
                    if (damage != null)
                    {
                        damage.Hitpoints = MathUtils.Min(damage.Hitpoints + amount, 1f);
                    }
                    return false;
                });
                return SubmitResult.Success;
            });
            AddFunction("catchfire", delegate (CommandData commandData)     //使生物或方块着火
            {
                //catchfire type:default obj:tiger v:10
                if (commandData.Type == "default")
                {
                    string obj = (string)commandData.GetValue("obj");
                    int v = (int)commandData.GetValue("v");
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        ComponentOnFire componentOnFire = body.Entity.FindComponent<ComponentOnFire>();
                        if (componentOnFire != null)
                        {
                            componentOnFire.SetOnFire(null, v);
                        }
                        return false;
                    });
                }
                //catchfire type:block pos:3,3,3 v:10
                else if (commandData.Type == "block")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int v = (int)commandData.GetValue("v");
                    float fireExpandability = (float)v / 10f;
                    Project.FindSubsystem<SubsystemFireBlockBehavior>().SetCellOnFire(pos.X, pos.Y, pos.Z, fireExpandability);
                }
                return SubmitResult.Success;
            });
            AddFunction("teleport", delegate (CommandData commandData)      //传送玩家
            {
                //transmit type:default pos:3,3,3 @C
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    m_componentPlayer.ComponentBody.Position = new Vector3(pos) + new Vector3(0.5f, 0f, 0.5f);
                }
                //transmit type:spawn
                if (commandData.Type == "spawn")
                {
                    m_componentPlayer.ComponentBody.Position = m_componentPlayer.PlayerData.SpawnPosition;
                }
                return SubmitResult.Success;
            });
            AddFunction("spawn", delegate (CommandData commandData)         //设置玩家重生点
            {
                //spawn type:default pos:3,3,3 @C
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    m_componentPlayer.PlayerData.SpawnPosition = new Vector3(pos) + new Vector3(0.5f, 0f, 0.5f);
                }
                //spawn type:playerpos
                else if (commandData.Type == "playerpos")
                {
                    m_componentPlayer.PlayerData.SpawnPosition = m_componentPlayer.ComponentBody.Position;
                }
                return SubmitResult.Success;
            });
            AddFunction("boxstage", delegate (CommandData commandData)      //设置玩家碰撞箱
            {
                //boxstage type:default/short/wide/flat/high/huge
                bool result = SetPlayerBoxStage(commandData.Type);
                if (result) m_playerBoxStage = commandData.Type;
                return SubmitResult.Success;
            });
            AddFunction("level", delegate (CommandData commandData)         //设置玩家等级
            {
                //level type:default v:10
                int v = (int)commandData.GetValue("v");
                m_componentPlayer.PlayerData.Level = v;
                return SubmitResult.Success;
            });
            AddFunction("stats", delegate (CommandData commandData)         //设置玩家属性
            {
                //stats type:default
                if (commandData.Type == "default")
                {
                    float health = m_componentPlayer.ComponentHealth.Health * 100f;
                    float food = m_componentPlayer.ComponentVitalStats.Food * 100f;
                    float sleep = m_componentPlayer.ComponentVitalStats.Sleep * 100f;
                    float stamina = m_componentPlayer.ComponentVitalStats.Stamina * 100f;
                    float wetness = m_componentPlayer.ComponentVitalStats.Wetness * 100f;
                    float temperature = m_componentPlayer.ComponentVitalStats.Temperature;
                    float attack = m_componentPlayer.ComponentMiner.AttackPower;
                    float defense = m_componentPlayer.ComponentHealth.AttackResilience;
                    float speed = m_componentPlayer.ComponentLocomotion.WalkSpeed * 10f;
                    string show = string.Format("生命值:{0}%，饥饿度:{1}%，疲劳度:{2}%，", MathUtils.Round(health), MathUtils.Round(food), MathUtils.Round(sleep));
                    show += string.Format("\n耐力值:{0}%，体湿:{1}%, 体温:{2}", MathUtils.Round(stamina), MathUtils.Round(wetness), temperature);
                    show += string.Format("\n攻击力:{0}，防御值:{1}，行走速度:{2}", attack, defense, speed);
                    m_componentPlayer.ComponentGui.DisplaySmallMessage(show, Color.White, false, false);
                    return SubmitResult.Success;
                }
                int v = (int)commandData.GetValue("v");
                //stats type:health v:10
                if (commandData.Type == "health")
                {
                    m_componentPlayer.ComponentHealth.Health = (float)v / 100f;
                }
                //stats type:food v:10
                else if (commandData.Type == "food")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令stats类型food在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    m_componentPlayer.ComponentVitalStats.Food = (float)v / 100f;
                }
                //stats type:sleep v:10
                else if (commandData.Type == "sleep")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令stats类型sleep在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    m_componentPlayer.ComponentVitalStats.Sleep = (float)v / 100f;
                }
                //stats type:stamina v:10
                else if (commandData.Type == "stamina")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令stats类型stamina在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    m_componentPlayer.ComponentVitalStats.Stamina = (float)v / 100f;
                }
                //stats type:wetness v:10
                else if (commandData.Type == "wetness")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令stats类型wetness在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    m_componentPlayer.ComponentVitalStats.Wetness = (float)v / 100f;
                }
                //stats type:temperature v:10
                else if (commandData.Type == "temperature")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令stats类型temperature在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    m_componentPlayer.ComponentVitalStats.Temperature = (float)v;
                }
                //stats type:attack v:10
                else if (commandData.Type == "attack")
                {
                    m_componentPlayer.ComponentMiner.AttackPower = v;
                }
                //stats type:defense v:10
                else if (commandData.Type == "defense")
                {
                    m_componentPlayer.ComponentHealth.AttackResilience = v;
                    m_componentPlayer.ComponentHealth.FallResilience = v;
                    m_componentPlayer.ComponentHealth.FireResilience = 2 * v;
                }
                //stats type:speed v:10
                else if (commandData.Type == "speed")
                {
                    float num = (float)v / 10f;
                    m_componentPlayer.ComponentLocomotion.WalkSpeed = 2 * num;
                    m_componentPlayer.ComponentLocomotion.JumpSpeed = 3 * MathUtils.Sqrt(num);
                    m_componentPlayer.ComponentLocomotion.LadderSpeed = 1.5f * num;
                    m_componentPlayer.ComponentLocomotion.SwimSpeed = 1.5f * num;
                }
                return SubmitResult.Success;
            });
            AddFunction("action", delegate (CommandData commandData)        //控制玩家动作
            {
                //action type:default
                if (commandData.Type == "default")
                {
                    ComponentFirstPersonModel componentFirstPersonModel = m_componentPlayer.Entity.FindComponent<ComponentFirstPersonModel>(true);
                    componentFirstPersonModel.m_pokeAnimationTime = 5f;
                }
                //action type:moveup/movedown/moveleft/moveright v:10
                else if (commandData.Type.StartsWith("move"))
                {
                    int v = (int)commandData.GetValue("v");
                    Vector3 direction = DataHandle.GetPlayerEyesDirection(m_componentPlayer);
                    Vector3 vector = Vector3.Zero;
                    switch (commandData.Type)
                    {
                        case "moveup": vector = new Vector3(direction.X, direction.Y, direction.Z); break;
                        case "movedown": vector = new Vector3(-direction.X, -direction.Y, -direction.Z); break;
                        case "moveleft": vector = new Vector3(direction.Z, 0, -direction.X); break;
                        case "moveright": vector = new Vector3(-direction.Z, 0, direction.X); break;
                        default: break;
                    }
                    m_componentPlayer.ComponentBody.Velocity = (vector / vector.Length()) * (v / 10f);
                }
                //action type:lookup/lookdown/lookleft/lookright v:10
                else if (commandData.Type.StartsWith("look"))
                {
                    int v = (int)commandData.GetValue("v");
                    float angleX = m_componentPlayer.ComponentBody.Rotation.ToYawPitchRoll().X;
                    switch (commandData.Type)
                    {
                        case "lookup": m_componentPlayer.ComponentLocomotion.LookAngles += new Vector2(0, MathUtils.DegToRad(v)); break;
                        case "lookdown": m_componentPlayer.ComponentLocomotion.LookAngles += new Vector2(0, -MathUtils.DegToRad(v)); break;
                        case "lookleft": m_componentPlayer.ComponentBody.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, angleX + MathUtils.DegToRad(v)); break;
                        case "lookright": m_componentPlayer.ComponentBody.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, angleX - MathUtils.DegToRad(v)); break;
                        default: break;
                    }
                }
                //action type:jump v:10
                else if (commandData.Type == "jump")
                {
                    int v = (int)commandData.GetValue("v");
                    Vector3 vector = m_componentPlayer.ComponentBody.Velocity;
                    m_componentPlayer.ComponentBody.Velocity = (vector.X, v / 10f, vector.Z);
                }
                //action type:rider con:true
                else if (commandData.Type == "rider")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con && m_componentPlayer.ComponentRider.Mount == null)
                    {
                        ComponentMount componentMount = m_componentPlayer.ComponentRider.FindNearestMount();
                        if (componentMount != null)
                        {
                            m_componentPlayer.ComponentRider.StartMounting(componentMount);
                        }
                    }
                    if (!con && m_componentPlayer.ComponentRider.Mount != null)
                    {
                        m_componentPlayer.ComponentRider.StartDismounting();
                    }
                }
                //action type:sneak con:true
                else if (commandData.Type == "sneak")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.ComponentBody.IsSneaking = con;
                }
                //action type:sleep con:true
                else if (commandData.Type == "sleep")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con)
                    {
                        m_componentPlayer.ComponentSleep.Sleep(false);
                    }
                    else
                    {
                        m_componentPlayer.ComponentSleep.WakeUp();
                    }
                }
                //action type:cough con:true
                else if (commandData.Type == "cough")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con)
                    {
                        m_componentPlayer.ComponentFlu.Cough();
                    }
                    else
                    {
                        m_componentPlayer.ComponentFlu.m_coughDuration = 0f;
                    }
                }
                //action type:sneeze con:true
                else if (commandData.Type == "sneeze")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con)
                    {
                        m_componentPlayer.ComponentFlu.Sneeze();
                    }
                    else
                    {
                        m_componentPlayer.ComponentFlu.m_sneezeDuration = 0f;
                    }
                }
                //action type:hasflu con:true
                else if (commandData.Type == "hasflu")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con)
                    {
                        m_componentPlayer.ComponentFlu.StartFlu();
                    }
                    else
                    {
                        m_componentPlayer.ComponentFlu.m_fluDuration = 0f;
                    }
                }
                //action type:sick con:true
                else if (commandData.Type == "sick")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con)
                    {
                        m_componentPlayer.ComponentSickness.StartSickness();
                    }
                    else
                    {
                        m_componentPlayer.ComponentSickness.m_sicknessDuration = 0f;
                    }
                }
                //action type:invincible con:true
                else if (commandData.Type == "invincible")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.ComponentHealth.IsInvulnerable = con;
                }
                //action type:fixed con:true
                else if (commandData.Type == "fixed")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.ComponentBody.AirDrag = con ? new Vector2(1000, 1000) : new Vector2(0.25f, 0.25f);
                }
                //action type:breath con:true
                else if (commandData.Type == "breath")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.ComponentHealth.AirCapacity = con ? -1 : 10;
                }
                return SubmitResult.Success;
            });
            AddFunction("clothes", delegate (CommandData commandData)       //修改玩家衣物
            {
                //clothes type:default/removeid id:16587
                if (commandData.Type == "default" || commandData.Type == "removeid")
                {
                    int id = (int)commandData.GetValue("id");
                    Block block = BlocksManager.Blocks[Terrain.ExtractContents(id)];
                    bool IsRemoveid = (commandData.Type == "removeid");
                    if (!(block is ClothingBlock))
                    {
                        ShowSubmitTips(string.Format("id为{0}的物品不是衣物，请选择衣物", id));
                        return SubmitResult.Fail;
                    }
                    ClothingData clothingData = block.GetClothingData(id);
                    if (clothingData == null)
                    {
                        ShowSubmitTips(string.Format("id为{0}的衣物数据不存在", id));
                        return SubmitResult.Fail;
                    }
                    List<int> cloths = new List<int>();
                    if (!IsRemoveid)
                    {
                        foreach (int cid in m_componentPlayer.ComponentClothing.GetClothes(clothingData.Slot))
                        {
                            cloths.Add(cid);
                        }
                        cloths.Add(id);
                    }
                    else
                    {
                        foreach (int cid in m_componentPlayer.ComponentClothing.GetClothes(clothingData.Slot))
                        {
                            if (id != cid)
                            {
                                cloths.Add(cid);
                            }
                        }
                    }
                    m_componentPlayer.ComponentClothing.SetClothes(clothingData.Slot, cloths);
                }
                //clothes type:removeslot v:1
                else if (commandData.Type == "removeslot")
                {
                    int v = (int)commandData.GetValue("v");
                    ClothingSlot clothingSlot = (ClothingSlot)(v - 1);
                    m_componentPlayer.ComponentClothing.SetClothes(clothingSlot, new List<int>());
                }
                //clothes type:removeall
                else if (commandData.Type == "removeall")
                {
                    m_componentPlayer.ComponentClothing.SetClothes(ClothingSlot.Head, new List<int>());
                    m_componentPlayer.ComponentClothing.SetClothes(ClothingSlot.Torso, new List<int>());
                    m_componentPlayer.ComponentClothing.SetClothes(ClothingSlot.Legs, new List<int>());
                    m_componentPlayer.ComponentClothing.SetClothes(ClothingSlot.Feet, new List<int>());
                }
                return SubmitResult.Success;
            });
            AddFunction("interact", delegate (CommandData commandData)      //与方块进行交互
            {
                Point3 pos = GetOnePoint("pos", commandData);
                //interact type:default pos:0,1,0 @C
                if (commandData.Type == "default")
                {
                    SubsystemBlockBehaviors subsystemBlockBehaviors = base.Project.FindSubsystem<SubsystemBlockBehaviors>();
                    Vector3[] vectors = new Vector3[6]
                    {
                        new Vector3(1f, 0f, 0f),
                        new Vector3(0f, 1f, 0f),
                        new Vector3(0f, 0f, 1f),
                        new Vector3(-1f, 0f, 0f),
                        new Vector3(0f, -1f, 0f),
                        new Vector3(0f, 0f, -1f)
                    };
                    foreach (Vector3 vector in vectors)
                    {
                        Ray3 ray3 = new Ray3(new Vector3(pos) + new Vector3(0.5f), vector);
                        TerrainRaycastResult? terrainRaycastResult = m_componentPlayer.ComponentMiner.Raycast<TerrainRaycastResult>(ray3, RaycastMode.Interaction);
                        if (terrainRaycastResult.HasValue && terrainRaycastResult.Value.CellFace.Point == pos)
                        {
                            TerrainRaycastResult raycastResult = terrainRaycastResult.Value;
                            SubsystemBlockBehavior[] blockBehaviors = subsystemBlockBehaviors.GetBlockBehaviors(Terrain.ExtractContents(raycastResult.Value));
                            for (int i = 0; i < blockBehaviors.Length; i++)
                            {
                                blockBehaviors[i].OnInteract(raycastResult, m_componentPlayer.ComponentMiner);
                            }
                            break;
                        }
                    }
                }
                //interact type:chest/table/dispenser/furnace pos:0,1,0 @C
                else if (commandData.Type == "chest" || commandData.Type == "table" || commandData.Type == "dispenser" || commandData.Type == "furnace")
                {
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity != null && m_componentPlayer != null)
                    {
                        IInventory inventory = m_componentPlayer.ComponentMiner.Inventory;
                        switch (commandData.Type)
                        {
                            case "chest":
                                {
                                    ComponentChest componentChest = blockEntity.Entity.FindComponent<ComponentChest>();
                                    if (componentChest != null)
                                    {
                                        m_componentPlayer.ComponentGui.ModalPanelWidget = new ChestWidget(inventory, componentChest);
                                    }
                                    break;
                                }
                            case "table":
                                {
                                    ComponentCraftingTable componentTable = blockEntity.Entity.FindComponent<ComponentCraftingTable>();
                                    if (componentTable != null)
                                    {
                                        m_componentPlayer.ComponentGui.ModalPanelWidget = new CraftingTableWidget(inventory, componentTable);
                                    }
                                    break;
                                }
                            case "dispenser":
                                {
                                    ComponentDispenser componentDispenser = blockEntity.Entity.FindComponent<ComponentDispenser>();
                                    if (componentDispenser != null)
                                    {
                                        m_componentPlayer.ComponentGui.ModalPanelWidget = new DispenserWidget(inventory, componentDispenser);
                                    }
                                    break;
                                }
                            case "furnace":
                                {
                                    ComponentFurnace componentFurnace = blockEntity.Entity.FindComponent<ComponentFurnace>();
                                    if (componentFurnace != null)
                                    {
                                        m_componentPlayer.ComponentGui.ModalPanelWidget = new FurnaceWidget(inventory, componentFurnace);
                                    }
                                    break;
                                }
                            default: break;
                        }
                    }
                }
                //interact type:memorybank/truthcircuit/delaygate/battery pos:0,1,0 @C
                else if (commandData.Type == "memorybank" || commandData.Type == "truthcircuit" || commandData.Type == "delaygate" || commandData.Type == "battery")
                {
                    SubsystemElectricity subsystemElectricity = base.Project.FindSubsystem<SubsystemElectricity>();
                    int value = m_subsystemTerrain.Terrain.GetCellValue(pos.X, pos.Y, pos.Z);
                    switch (commandData.Type)
                    {
                        case "memorybank":
                            {
                                if (Terrain.ExtractContents(value) == 186)
                                {
                                    SubsystemMemoryBankBlockBehavior memoryBankBlockBehavior = base.Project.FindSubsystem<SubsystemMemoryBankBlockBehavior>();
                                    MemoryBankData memoryBankData = memoryBankBlockBehavior.GetBlockData(pos) ?? new MemoryBankData();
                                    DialogsManager.ShowDialog(m_componentPlayer.GuiWidget, new EditMemoryBankDialog(memoryBankData, delegate ()
                                    {
                                        memoryBankBlockBehavior.SetBlockData(pos, memoryBankData);
                                        int face = ((MemoryBankBlock)BlocksManager.Blocks[186]).GetFace(value);
                                        ElectricElement electricElement = subsystemElectricity.GetElectricElement(pos.X, pos.Y, pos.Z, face);
                                        if (electricElement != null)
                                        {
                                            subsystemElectricity.QueueElectricElementForSimulation(electricElement, subsystemElectricity.CircuitStep + 1);
                                        }
                                    }));
                                }
                                break;
                            }
                        case "truthcircuit":
                            {
                                if (Terrain.ExtractContents(value) == 188)
                                {
                                    SubsystemTruthTableCircuitBlockBehavior circuitBlockBehavior = base.Project.FindSubsystem<SubsystemTruthTableCircuitBlockBehavior>();
                                    TruthTableData truthTableData = circuitBlockBehavior.GetBlockData(pos) ?? new TruthTableData();
                                    DialogsManager.ShowDialog(m_componentPlayer.GuiWidget, new EditTruthTableDialog(truthTableData, delegate
                                    {
                                        circuitBlockBehavior.SetBlockData(pos, truthTableData);
                                        int face = ((TruthTableCircuitBlock)BlocksManager.Blocks[188]).GetFace(value);
                                        ElectricElement electricElement = subsystemElectricity.GetElectricElement(pos.X, pos.Y, pos.Z, face);
                                        if (electricElement != null)
                                        {
                                            subsystemElectricity.QueueElectricElementForSimulation(electricElement, subsystemElectricity.CircuitStep + 1);
                                        }
                                    }));
                                }
                                break;
                            }
                        case "delaygate":
                            {
                                if (Terrain.ExtractContents(value) == 224)
                                {
                                    int data = Terrain.ExtractData(value);
                                    int delay = AdjustableDelayGateBlock.GetDelay(data);
                                    DialogsManager.ShowDialog(m_componentPlayer.GuiWidget, new EditAdjustableDelayGateDialog(delay, delegate (int newDelay)
                                    {
                                        int num = AdjustableDelayGateBlock.SetDelay(data, newDelay);
                                        if (num != data)
                                        {
                                            int value2 = Terrain.ReplaceData(value, num);
                                            m_subsystemTerrain.ChangeCell(pos.X, pos.Y, pos.Z, value2);
                                            int face = ((AdjustableDelayGateBlock)BlocksManager.Blocks[224]).GetFace(value);
                                            ElectricElement electricElement = subsystemElectricity.GetElectricElement(pos.X, pos.Y, pos.Z, face);
                                            if (electricElement != null)
                                            {
                                                subsystemElectricity.QueueElectricElementForSimulation(electricElement, subsystemElectricity.CircuitStep + 1);
                                            }
                                        }
                                    }));
                                }
                                break;
                            }
                        case "battery":
                            {
                                if (Terrain.ExtractContents(value) == 138)
                                {
                                    int data = Terrain.ExtractData(value);
                                    int voltageLevel = BatteryBlock.GetVoltageLevel(data);
                                    DialogsManager.ShowDialog(m_componentPlayer.GuiWidget, new EditVoltageLevelDialog(voltageLevel, delegate (int newVoltageLevel)
                                    {
                                        int num = BatteryBlock.SetVoltageLevel(data, newVoltageLevel);
                                        if (num != data)
                                        {
                                            int value2 = Terrain.ReplaceData(value, num);
                                            m_subsystemTerrain.ChangeCell(pos.X, pos.Y, pos.Z, value2);
                                            ElectricElement electricElement = subsystemElectricity.GetElectricElement(pos.X, pos.Y, pos.Z, 4);
                                            if (electricElement != null)
                                            {
                                                subsystemElectricity.QueueElectricElementConnectionsForSimulation(electricElement, subsystemElectricity.CircuitStep + 1);
                                            }
                                        }
                                    }));
                                }
                                break;
                            }
                        default: break;
                    }
                }
                //interact type:sign pos:0,1,0 @C
                else if (commandData.Type == "sign")
                {
                    int id = m_subsystemTerrain.Terrain.GetCellContents(pos.X, pos.Y, pos.Z);
                    if (id == 97 || id == 210)
                    {
                        SubsystemSignBlockBehavior subsystemSignBlockBehavior = base.Project.FindSubsystem<SubsystemSignBlockBehavior>(true);
                        DialogsManager.ShowDialog(m_componentPlayer.GuiWidget, new EditSignDialog(subsystemSignBlockBehavior, pos));
                    }
                }
                //interact type:command pos:0,1,0 @C
                else if (commandData.Type == "command")
                {
                    int id = m_subsystemTerrain.Terrain.GetCellContents(pos.X, pos.Y, pos.Z);
                    if (id == CommandBlock.Index)
                    {
                        m_componentPlayer.ComponentGui.ModalPanelWidget = new CommandEditWidget(base.Project, m_componentPlayer, pos);
                    }
                }
                //interact type:button pos:0,1,0 @C
                else if (commandData.Type == "button")
                {
                    SubsystemElectricity subsystemElectricity = base.Project.FindSubsystem<SubsystemElectricity>();
                    int value = m_subsystemTerrain.Terrain.GetCellValue(pos.X, pos.Y, pos.Z);
                    if (Terrain.ExtractContents(value) == 142)
                    {
                        int face = ((ButtonBlock)BlocksManager.Blocks[142]).GetFace(value);
                        ElectricElement Element = subsystemElectricity.GetElectricElement(pos.X, pos.Y, pos.Z, face);
                        if (Element != null)
                        {
                            ((ButtonElectricElement)Element).Press();
                        }
                    }
                }
                //interact type:switch pos:0,1,0 @C
                else if (commandData.Type == "switch")
                {
                    int value = m_subsystemTerrain.Terrain.GetCellValue(pos.X, pos.Y, pos.Z);
                    if (Terrain.ExtractContents(value) == 141)
                    {
                        int newValue = SwitchBlock.SetLeverState(value, !SwitchBlock.GetLeverState(value));
                        m_subsystemTerrain.ChangeCell(pos.X, pos.Y, pos.Z, newValue);
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("widget", delegate (CommandData commandData)        //控制界面
            {
                //widget type:default opt:clothing
                if (commandData.Type == "default")
                {
                    string opt = (string)commandData.GetValue("opt");
                    switch (opt)
                    {
                        case "clothing":
                            {
                                if (!(m_componentPlayer.ComponentGui.ModalPanelWidget is ClothingWidget))
                                {
                                    m_componentPlayer.ComponentGui.ModalPanelWidget = new ClothingWidget(m_componentPlayer);
                                }
                                break;
                            }
                        case "stats":
                            {
                                if (!(m_componentPlayer.ComponentGui.ModalPanelWidget is VitalStatsWidget))
                                {
                                    m_componentPlayer.ComponentGui.ModalPanelWidget = new VitalStatsWidget(m_componentPlayer);
                                }
                                break;
                            }
                        case "inventory":
                            {
                                if (m_gameMode == GameMode.Creative)
                                {
                                    if (!(m_componentPlayer.ComponentGui.ModalPanelWidget is CreativeInventoryWidget))
                                    {
                                        m_componentPlayer.ComponentGui.ModalPanelWidget = new CreativeInventoryWidget(m_componentPlayer.Entity);
                                    }
                                }
                                else
                                {
                                    if (!(m_componentPlayer.ComponentGui.ModalPanelWidget is FullInventoryWidget))
                                    {
                                        ComponentCraftingTable componentCraftingTable = m_componentPlayer.Entity.FindComponent<ComponentCraftingTable>(throwOnError: true);
                                        m_componentPlayer.ComponentGui.ModalPanelWidget = new FullInventoryWidget(m_componentPlayer.ComponentMiner.Inventory, componentCraftingTable);
                                    }
                                }
                                break;
                            }
                        default: break;
                    }
                }
                //widget type:close
                else if (commandData.Type == "close")
                {
                    if (m_componentPlayer.ComponentGui.ModalPanelWidget != null)
                    {
                        m_componentPlayer.ComponentGui.ModalPanelWidget = null;
                    }
                }
                //widget type:hidegui con:true
                else if (commandData.Type == "hidegui")
                {
                    bool con = (bool)commandData.GetValue("con");
                    if (con)
                    {
                        if (m_aimingSightsBatches == null)
                        {
                            m_aimingSightsBatches = m_componentPlayer.ComponentAimingSights.m_primitivesRenderer3D.m_allBatches.ToList();
                        }
                        m_componentPlayer.ComponentAimingSights.m_primitivesRenderer3D.m_allBatches.Clear();
                        m_componentPlayer.ComponentGui.ShortInventoryWidget.IsDrawEnabled = false;
                        m_componentPlayer.ComponentGui.m_moveContainerWidget.IsDrawEnabled = false;
                        m_componentPlayer.ComponentGui.m_lookContainerWidget.IsDrawEnabled = false;
                        m_componentPlayer.ComponentGui.m_leftControlsContainerWidget.IsDrawEnabled = false;
                        m_componentPlayer.ComponentGui.m_rightControlsContainerWidget.IsDrawEnabled = false;
                    }
                    else
                    {
                        if (m_aimingSightsBatches != null)
                        {
                            m_componentPlayer.ComponentAimingSights.m_primitivesRenderer3D.m_allBatches = m_aimingSightsBatches.ToList();
                        }
                        m_componentPlayer.ComponentGui.ShortInventoryWidget.IsDrawEnabled = true;
                        m_componentPlayer.ComponentGui.m_moveContainerWidget.IsDrawEnabled = true;
                        m_componentPlayer.ComponentGui.m_lookContainerWidget.IsDrawEnabled = true;
                        m_componentPlayer.ComponentGui.m_leftControlsContainerWidget.IsDrawEnabled = true;
                        m_componentPlayer.ComponentGui.m_rightControlsContainerWidget.IsDrawEnabled = true;
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("adddrop", delegate (CommandData commandData)       //添加掉落物
            {
                //adddrop type:default pos:0,0,0 id:46 v:10
                Point3 pos = GetOnePoint("pos", commandData);
                int id = (int)commandData.GetValue("id");
                int v = (int)commandData.GetValue("v");
                for (int i = 0; i < v; i++)
                {
                    m_subsystemPickables.AddPickable(id, 1, new Vector3(pos) + new Vector3(new Random().Float(0.4f, 0.6f)), null, null);
                }
                return SubmitResult.Success;
            });
            AddFunction("removedrop", delegate (CommandData commandData)    //移除掉落物
            {
                //removedrop type:default id:46
                if (commandData.Type == "default")
                {
                    int id = (int)commandData.GetValue("id");
                    foreach (Pickable pickable in m_subsystemPickables.Pickables)
                    {
                        if (pickable.Value == id)
                        {
                            pickable.ToRemove = true;
                        }
                    }
                }
                //removedrop type:area pos1:0,0,0 pos2:1,1,1
                else if (commandData.Type == "area")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    foreach (Pickable pickable in m_subsystemPickables.Pickables)
                    {
                        if (cubeArea.Exist(pickable.Position))
                        {
                            pickable.ToRemove = true;
                        }
                    }
                }
                //removedrop type:limarea pos1:0,0,0 pos2:1,1,1 id:46
                else if (commandData.Type == "limarea")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    foreach (Pickable pickable in m_subsystemPickables.Pickables)
                    {
                        if (cubeArea.Exist(pickable.Position) && pickable.Value == id)
                        {
                            pickable.ToRemove = true;
                        }
                    }
                }
                //removedrop type:all
                else if (commandData.Type == "all")
                {
                    foreach (Pickable pickable in m_subsystemPickables.Pickables)
                    {
                        pickable.ToRemove = true;
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("launchdrop", delegate (CommandData commandData)    //发射掉落物
            {
                //launchdrop type:default pos:0,0,0 id:46 vec3:5,5,5
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    m_subsystemPickables.AddPickable(id, 1, new Vector3(pos) + new Vector3(0.5f), vec3, null);
                }
                //launchdrop type:area pos1:0,0,0 pos2:1,1,1 id:46 vec3:5,5,5
                else if (commandData.Type == "area")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    foreach (Pickable pickable in m_subsystemPickables.Pickables)
                    {
                        if (cubeArea.Exist(pickable.Position) && pickable.Value == id)
                        {
                            pickable.Velocity = vec3;
                        }
                    }
                }
                //launchdrop type:gather/spread pos:0,0,0 v:10
                else if (commandData.Type == "gather" || commandData.Type == "spread")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int v = (int)commandData.GetValue("v");
                    bool isGather = (commandData.Type == "gather");
                    foreach (Pickable pickable in m_subsystemPickables.Pickables)
                    {
                        Vector3 vector = new Vector3(pos) - pickable.Position;
                        if (!isGather) vector = -vector;
                        pickable.Velocity = (vector / vector.Length()) * (v / 10f);
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("additem", delegate (CommandData commandData)       //添加物品
            {
                int id = (int)commandData.GetValue("id");
                int v = (int)commandData.GetValue("v");
                //additem type:default/inventory/craft id:46 s:1 v:3
                if (commandData.Type == "default" || commandData.Type == "inventory" || commandData.Type == "craft")
                {
                    int s = (int)commandData.GetValue("s");
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令additem类型" + commandData.Type + "在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    bool isCraft = (commandData.Type == "craft");
                    int slot = -1;
                    ComponentInventoryBase inventory = m_componentPlayer.Entity.FindComponent<ComponentInventoryBase>();
                    ComponentCraftingTable craftingTable = m_componentPlayer.Entity.FindComponent<ComponentCraftingTable>();
                    if (inventory != null && craftingTable != null)
                    {
                        List<ComponentInventoryBase.Slot> inventoryBase = !isCraft ? inventory.m_slots : craftingTable.m_slots;
                        switch (commandData.Type)
                        {
                            case "default": slot = s - 1; break;
                            case "inventory": slot = s + 9; break;
                            case "craft": slot = s - 1; break;
                            default: break;
                        }
                        if (inventoryBase[slot].Value == id)
                        {
                            inventoryBase[slot].Count += v;
                        }
                        else
                        {
                            inventoryBase[slot].Value = id;
                            inventoryBase[slot].Count = v;
                        }
                    }
                }
                // additem type:hand id:46 v:3
                else if (commandData.Type == "hand")
                {
                    ComponentInventoryBase inventory = m_componentPlayer.Entity.FindComponent<ComponentInventoryBase>();
                    int activeValue = inventory.GetSlotValue(inventory.ActiveSlotIndex);
                    int activeCount = inventory.GetSlotCount(inventory.ActiveSlotIndex);
                    if (activeValue == id)
                    {
                        inventory.RemoveSlotItems(inventory.ActiveSlotIndex, activeCount);
                        inventory.AddSlotItems(inventory.ActiveSlotIndex, id, activeCount + v);
                    }
                    else
                    {
                        inventory.RemoveSlotItems(inventory.ActiveSlotIndex, activeCount);
                        inventory.AddSlotItems(inventory.ActiveSlotIndex, id, v);
                    }
                }
                //additem type:chest/table/dispenser/furnace pos:0,0,0 id:46 s:1 v:3
                else if (commandData.Type == "chest" || commandData.Type == "table" || commandData.Type == "dispenser" || commandData.Type == "furnace")
                {
                    int s = (int)commandData.GetValue("s");
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    List<ComponentInventoryBase.Slot> inventoryBase = null;
                    try
                    {
                        switch (commandData.Type)
                        {
                            case "chest": inventoryBase = blockEntity.Entity.FindComponent<ComponentChest>().m_slots; break;
                            case "table": inventoryBase = blockEntity.Entity.FindComponent<ComponentCraftingTable>().m_slots; break;
                            case "dispenser": inventoryBase = blockEntity.Entity.FindComponent<ComponentDispenser>().m_slots; break;
                            case "furnace": inventoryBase = blockEntity.Entity.FindComponent<ComponentFurnace>().m_slots; break;
                            default: break;
                        }
                    }
                    catch
                    {
                        return SubmitResult.Fail;
                    }
                    if (inventoryBase[s - 1].Value == id)
                    {
                        inventoryBase[s - 1].Count += v;
                    }
                    else
                    {
                        inventoryBase[s - 1].Value = id;
                        inventoryBase[s - 1].Count = v;
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("removeitem", delegate (CommandData commandData)    //移除物品
            {
                int s = (int)commandData.GetValue("s");
                int v = (int)commandData.GetValue("v");
                //removeitem type:default/inventory/craft s:1 v:3
                if (commandData.Type == "default" || commandData.Type == "inventory" || commandData.Type == "craft")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令removeitem类型" + commandData.Type + "在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    bool isCraft = (commandData.Type == "craft");
                    int slot = -1;
                    ComponentInventoryBase inventory = m_componentPlayer.Entity.FindComponent<ComponentInventoryBase>();
                    ComponentCraftingTable craftingTable = m_componentPlayer.Entity.FindComponent<ComponentCraftingTable>();
                    if (inventory != null && craftingTable != null)
                    {
                        List<ComponentInventoryBase.Slot> inventoryBase = !isCraft ? inventory.m_slots : craftingTable.m_slots;
                        switch (commandData.Type)
                        {
                            case "default": slot = s - 1; break;
                            case "inventory": slot = s + 9; break;
                            case "craft": slot = s - 1; break;
                            default: break;
                        }
                        if (inventoryBase[slot].Count < v)
                        {
                            inventoryBase[slot].Count = 0;
                        }
                        else
                        {
                            inventoryBase[slot].Count = inventoryBase[slot].Count - v;
                        }
                    }
                }
                //removeitem type:chest/table/dispenser/furnace pos:0,0,0 s:1 v:3
                else if (commandData.Type == "chest" || commandData.Type == "table" || commandData.Type == "dispenser" || commandData.Type == "furnace")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    List<ComponentInventoryBase.Slot> inventoryBase = null;
                    try
                    {
                        switch (commandData.Type)
                        {
                            case "chest": inventoryBase = blockEntity.Entity.FindComponent<ComponentChest>().m_slots; break;
                            case "table": inventoryBase = blockEntity.Entity.FindComponent<ComponentCraftingTable>().m_slots; break;
                            case "dispenser": inventoryBase = blockEntity.Entity.FindComponent<ComponentDispenser>().m_slots; break;
                            case "furnace": inventoryBase = blockEntity.Entity.FindComponent<ComponentFurnace>().m_slots; break;
                            default: break;
                        }
                    }
                    catch
                    {
                        return SubmitResult.Fail;
                    }
                    if (inventoryBase[s - 1].Count < v)
                    {
                        inventoryBase[s - 1].Count = 0;
                    }
                    else
                    {
                        inventoryBase[s - 1].Count = inventoryBase[s - 1].Count - v;
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("clearitem", delegate (CommandData commandData)     //清空物品
            {
                //clearitem type:default/inventory/craft
                if (commandData.Type == "default" || commandData.Type == "inventory" || commandData.Type == "craft")
                {
                    if (m_gameMode == GameMode.Creative)
                    {
                        ShowSubmitTips("指令clearitem类型" + commandData.Type + "在非创造模式下提交才有效");
                        return SubmitResult.Fail;
                    }
                    bool isCraft = (commandData.Type == "craft");
                    int slot = 0;
                    int num = 0;
                    ComponentInventoryBase inventory = m_componentPlayer.Entity.FindComponent<ComponentInventoryBase>();
                    ComponentCraftingTable craftingTable = m_componentPlayer.Entity.FindComponent<ComponentCraftingTable>();
                    if (inventory != null && craftingTable != null)
                    {
                        List<ComponentInventoryBase.Slot> inventoryBase = !isCraft ? inventory.m_slots : craftingTable.m_slots;
                        switch (commandData.Type)
                        {
                            case "default": slot = 0; num = 10; break;
                            case "inventory": slot = 10; num = 16; break;
                            case "craft": slot = 0; num = 6; break;
                            default: break;
                        }
                        for (int i = 0; i < num; i++)
                        {
                            inventoryBase[slot + i].Count = 0;
                        }
                    }
                }
                //clearitem type:chest/table/dispenser/furnace pos:0,0,0
                else if (commandData.Type == "chest" || commandData.Type == "table" || commandData.Type == "dispenser" || commandData.Type == "furnace")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    List<ComponentInventoryBase.Slot> inventoryBase = null;
                    try
                    {
                        switch (commandData.Type)
                        {
                            case "chest": inventoryBase = blockEntity.Entity.FindComponent<ComponentChest>().m_slots; break;
                            case "table": inventoryBase = blockEntity.Entity.FindComponent<ComponentCraftingTable>().m_slots; break;
                            case "dispenser": inventoryBase = blockEntity.Entity.FindComponent<ComponentDispenser>().m_slots; break;
                            case "furnace": inventoryBase = blockEntity.Entity.FindComponent<ComponentFurnace>().m_slots; break;
                            default: break;
                        }
                    }
                    catch
                    {
                        return SubmitResult.Fail;
                    }
                    foreach (var slot in inventoryBase)
                    {
                        slot.Count = 0;
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("explosion", delegate (CommandData commandData)     //引发爆炸
            {
                //explosion type:default pos:0,0,0 v:50
                Point3 pos = GetOnePoint("pos", commandData);
                int v = (int)commandData.GetValue("v");
                SubsystemExplosions subsystemExplosions = base.Project.FindSubsystem<SubsystemExplosions>();
                subsystemExplosions.AddExplosion(pos.X, pos.Y, pos.Z, v, isIncendiary: false, noExplosionSound: false);
                return SubmitResult.Success;
            });
            AddFunction("lightning", delegate (CommandData commandData)     //召唤闪电
            {
                //lightning type:default pos:0,0,0
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    base.Project.FindSubsystem<SubsystemSky>().MakeLightningStrike(new Vector3(pos) + new Vector3(0.5f),true);
                }
                //lightning type:area pos1:0,0,0 pos2:1,1,1 color:255,255,255 v1:10 v2:10
                else if (commandData.Type == "area")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    Color color = (Color)commandData.GetValue("color");
                    int v1 = (int)commandData.GetValue("v1");
                    int v2 = (int)commandData.GetValue("v2");
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    int splitX = (int)((float)cubeArea.LengthX * (1 - (float)v1 / 100f)) + 1;
                    int splitZ = (int)((float)cubeArea.LengthZ * (1 - (float)v1 / 100f)) + 1;
                    SubsystemExplosions subsystemExplosions = base.Project.FindSubsystem<SubsystemExplosions>();
                    cubeArea.Ergodic(delegate
                    {
                        bool flag = (cubeArea.MinPoint.Y == cubeArea.Current.Y);
                        bool flag2 = ((cubeArea.Current.X - cubeArea.MinPoint.X) % splitX == 0);
                        bool flag3 = ((cubeArea.Current.Z - cubeArea.MinPoint.Z) % splitZ == 0);
                        if (flag && flag2 && flag3)
                        {
                            cubeArea.Current.Y = m_subsystemTerrain.Terrain.GetTopHeight(cubeArea.Current.X, cubeArea.Current.Z);
                            Vector3 vector = new Vector3(cubeArea.Current) + new Vector3((new Random()).Float(0, 1f));
                            m_subsystemParticles.AddParticleSystem(new LightningStrikeParticleSystem(vector, color));
                            subsystemExplosions.AddExplosion(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z, v2, false, false);
                        }
                        return false;
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("rain", delegate (CommandData commandData)          //控制下雨
            {
                //rain type:default con:true color:255,255,255
                SubsystemWeather subsystemWeather = base.Project.FindSubsystem<SubsystemWeather>();
                bool con = (bool)commandData.GetValue("con");
                Color color = (Color)commandData.GetValue("color");
                m_rainColor = color;
                if (con)
                {
                    subsystemWeather.PrecipitationIntensity = 1f;
                    subsystemWeather.m_precipitationStartTime = 0f;
                }
                else
                {
                    subsystemWeather.PrecipitationIntensity = 0f;
                    subsystemWeather.m_precipitationEndTime = 0f;
                }
                return SubmitResult.Success;
            });
            AddFunction("skycolor", delegate (CommandData commandData)      //更改天空颜色
            {
                //skycolor type:default color:255,255,255
                Color color = (Color)commandData.GetValue("color");
                m_skyColor = color;
                return SubmitResult.Success;
            });
            AddFunction("temperature", delegate (CommandData commandData)   //设置温度
            {
                //temperature type:default pos1:0,0,0 pos2:1,1,1 v:5
                Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                int v = (int)commandData.GetValue("v");
                CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                Point2 chunkPos = Terrain.ToChunk(cubeArea.MinPoint.X, cubeArea.MinPoint.Z);
                Point2 chunkPos2 = Terrain.ToChunk(cubeArea.MaxPoint.X, cubeArea.MaxPoint.Z);
                for (int i = chunkPos.X; i <= chunkPos2.X; i++)
                {
                    for (int j = chunkPos.Y; j <= chunkPos2.Y; j++)
                    {
                        TerrainChunk chunk = m_subsystemTerrain.Terrain.GetChunkAtCoords(i, j);
                        for (int x = 0; x < 16; x++)
                        {
                            for (int z = 0; z < 16; z++)
                            {
                                if (cubeArea.Exist(new Vector3(x + chunk.Origin.X, cubeArea.Center.Y, z + chunk.Origin.Y)))
                                {
                                    chunk.SetTemperatureFast(x, z, v);
                                }
                            }
                        }
                    }
                }
                Time.QueueTimeDelayedExecution(Time.RealTime + 1f, delegate
                {
                    m_subsystemTerrain.TerrainUpdater.DowngradeAllChunksState(TerrainChunkState.InvalidVertices1, forceGeometryRegeneration: false);
                });
                return SubmitResult.Success;
            });
            AddFunction("humidity", delegate (CommandData commandData)      //设置湿度
            {
                //humidity type:default pos1:0,0,0 pos2:1,1,1 v:5
                Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                int v = (int)commandData.GetValue("v");
                CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                Point2 chunkPos = Terrain.ToChunk(cubeArea.MinPoint.X, cubeArea.MinPoint.Z);
                Point2 chunkPos2 = Terrain.ToChunk(cubeArea.MaxPoint.X, cubeArea.MaxPoint.Z);
                for (int i = chunkPos.X; i <= chunkPos2.X; i++)
                {
                    for (int j = chunkPos.Y; j <= chunkPos2.Y; j++)
                    {
                        TerrainChunk chunk = m_subsystemTerrain.Terrain.GetChunkAtCoords(i, j);
                        for (int x = 0; x < 16; x++)
                        {
                            for (int z = 0; z < 16; z++)
                            {
                                if (cubeArea.Exist(new Vector3(x + chunk.Origin.X, cubeArea.Center.Y, z + chunk.Origin.Y)))
                                {
                                    chunk.SetHumidityFast(x, z, v);
                                }
                            }
                        }
                    }
                }
                Time.QueueTimeDelayedExecution(Time.RealTime + 1f, delegate
                {
                    m_subsystemTerrain.TerrainUpdater.DowngradeAllChunksState(TerrainChunkState.InvalidVertices1, forceGeometryRegeneration: false);
                });
                return SubmitResult.Success;
            });
            AddFunction("copyblock", delegate (CommandData commandData)     //复制方块区域
            {
                WithdrawBlockManager wbManager = null;
                if (WithdrawBlockManager.WithdrawMode) wbManager = new WithdrawBlockManager();
                Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                Point3 pos3 = GetOnePoint("pos3", commandData);
                CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                //copyblock type:default pos1:0,0,0 pos2:1,1,1 pos3:2,2,2 pos4:3,3,3 con1:false con2:false
                if (commandData.Type == "default")
                {
                    Point3 pos4 = (Point3)commandData.GetValue("pos4");
                    bool con1 = (bool)commandData.GetValue("con1");
                    bool con2 = (bool)commandData.GetValue("con2");
                    CopyBlockManager copyBlockManager = new CopyBlockManager(this, wbManager, cubeArea.MinPoint, cubeArea.MaxPoint, false, con1, false);
                    copyBlockManager.CopyOrigin = pos3;
                    if (con2)
                    {
                        copyBlockManager.ClearBlockArea();
                        PlaceReprocess(wbManager, commandData, true, cubeArea.MinPoint, cubeArea.MaxPoint);
                    }
                    copyBlockManager.DirectCopy(pos4, con1);
                    PlaceReprocess(wbManager, commandData, true, pos4 - pos3 + cubeArea.MinPoint, pos4 - pos3 + cubeArea.MaxPoint);
                }
                //copyblock type:copycache pos1:0,0,0 pos2:1,1,1 pos3:2,2,2
                else if (commandData.Type == "copycache")
                {
                    CopyBlockManager = new CopyBlockManager(this, wbManager, cubeArea.MinPoint, cubeArea.MaxPoint, true, false, false);
                    CopyBlockManager.CopyOrigin = pos3;
                    ShowSubmitTips("建筑已复制到缓存区，可以过视距或跨存档生成\n建筑生成指令build");
                }
                //copyblock type:rotate pos1:0,0,0 pos2:1,1,1 pos3:2,2,2 opt1:axis+y opt2:+90 con:false
                else if (commandData.Type == "rotate")
                {
                    string opt1 = (string)commandData.GetValue("opt1");
                    string opt2 = (string)commandData.GetValue("opt2");
                    bool con = (bool)commandData.GetValue("con");
                    CopyBlockManager copyBlockManager = new CopyBlockManager(this, wbManager, cubeArea.MinPoint, cubeArea.MaxPoint);
                    if (con)
                    {
                        copyBlockManager.ClearBlockArea();
                        PlaceReprocess(wbManager, commandData, true, cubeArea.MinPoint, cubeArea.MaxPoint);
                    }
                    copyBlockManager.RotateCopy(pos3, opt1, opt2);
                    Point3 completePoint = copyBlockManager.GetRotatePoint(copyBlockManager.CubeArea.MinPoint, pos3, opt1, opt2);
                    Point3 completePoint2 = copyBlockManager.GetRotatePoint(copyBlockManager.CubeArea.MaxPoint, pos3, opt1, opt2);
                    CubeArea completeCubeArea = new CubeArea(completePoint, completePoint2);
                    PlaceReprocess(wbManager, commandData, true, completeCubeArea.MinPoint, completeCubeArea.MaxPoint);
                }
                //copyblock type:mirror pos1:0,0,0 pos2:1,1,1 pos3:2,2,2 opt:xoy con1:false con2:false
                else if (commandData.Type == "mirror")
                {
                    string opt = (string)commandData.GetValue("opt");
                    bool con1 = (bool)commandData.GetValue("con1");
                    bool con2 = (bool)commandData.GetValue("con2");
                    CopyBlockManager copyBlockManager = new CopyBlockManager(this, wbManager, cubeArea.MinPoint, cubeArea.MaxPoint);
                    if (con1)
                    {
                        copyBlockManager.ClearBlockArea();
                        PlaceReprocess(wbManager, commandData, true, cubeArea.MinPoint, cubeArea.MaxPoint);
                    }
                    copyBlockManager.MirrorCopy(pos3, opt, con2);
                    Point3 completePoint = copyBlockManager.GetMirrorPoint(copyBlockManager.CubeArea.MinPoint, pos3, opt, con2);
                    Point3 completePoint2 = copyBlockManager.GetMirrorPoint(copyBlockManager.CubeArea.MaxPoint, pos3, opt, con2);
                    CubeArea completeCubeArea = new CubeArea(completePoint, completePoint2);
                    PlaceReprocess(wbManager, commandData, true, completeCubeArea.MinPoint, completeCubeArea.MaxPoint);
                }
                //copyblock type:enlarge pos1:0,0,0 pos2:1,1,1 pos3:2,2,2
                else if (commandData.Type == "enlarge")
                {
                    cubeArea.Ergodic(delegate
                    {
                        int x = cubeArea.Current.X - cubeArea.MinPoint.X;
                        int y = cubeArea.Current.Y - cubeArea.MinPoint.Y;
                        int z = cubeArea.Current.Z - cubeArea.MinPoint.Z;
                        int value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                        int data = Terrain.ExtractData(value);
                        Block block = BlocksManager.Blocks[Terrain.ExtractContents(value)];
                        bool IsCubeBlock = block is CubeBlock;
                        bool IsStairsBlock = block is StairsBlock;
                        bool IsSlabBlock = block is SlabBlock;
                        if (IsCubeBlock || IsStairsBlock || IsSlabBlock)
                        {
                            int l = 0;
                            int realValue = 0;
                            for (int i = 0; i < 2; i++)
                            {
                                for (int j = 0; j < 2; j++)
                                {
                                    for (int k = 0; k < 2; k++)
                                    {
                                        if (IsCubeBlock) realValue = value;
                                        else if (IsStairsBlock) realValue = DataHandle.GetStairValue(value, l);
                                        else if (IsSlabBlock) realValue = DataHandle.GetSlabValue(value, l);
                                        ChangeBlockValue(wbManager, pos3.X + 2 * x + j, pos3.Y + 2 * y + i, pos3.Z + 2 * z + k, realValue);
                                        l++;
                                    }
                                }
                            }
                        }
                        return false;
                    });
                    PlaceReprocess(wbManager, commandData, true, pos3, pos3 + new Point3(cubeArea.LengthX * 2, cubeArea.LengthY * 2, cubeArea.LengthZ * 2));
                }
                //copyblock type:aroundaxis pos1:0,0,0 pos2:1,1,1 pos3:2,2,2 opt:y
                else if (commandData.Type == "aroundaxis")
                {
                    string opt = (string)commandData.GetValue("opt");
                    Task.Run(delegate
                    {
                        Dictionary<int, Dictionary<int, int>> hightLens = new Dictionary<int, Dictionary<int, int>>();
                        cubeArea.Ergodic(delegate
                        {
                            int value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                            if (Terrain.ExtractContents(value) != 0)
                            {
                                int key = cubeArea.Current.Y;
                                int l1 = (cubeArea.Current.X - pos3.X);
                                int l2 = (cubeArea.Current.Z - pos3.Z);
                                if (opt == "x")
                                {
                                    key = cubeArea.Current.X;
                                    l1 = (cubeArea.Current.Y - pos3.Y);
                                }
                                else if (opt == "z")
                                {
                                    key = cubeArea.Current.Z;
                                    l2 = (cubeArea.Current.Y - pos3.Y);
                                }
                                if (!hightLens.ContainsKey(key))
                                {
                                    hightLens[key] = new Dictionary<int, int>();
                                }
                                int len = l1 * l1 + l2 * l2;
                                len = (int)MathUtils.Sqrt((float)len);
                                if (!hightLens[key].ContainsKey(len))
                                {
                                    hightLens[key][len] = value;
                                }
                            }
                            return false;
                        });
                        int maxLength = 0;
                        foreach (int h in hightLens.Keys)
                        {
                            foreach (int l in hightLens[h].Keys)
                            {
                                if (l > maxLength) maxLength = l;
                                for (int i1 = -l; i1 <= l; i1++)
                                {
                                    for (int i2 = -l; i2 <= l; i2++)
                                    {
                                        if (MathUtils.Abs(i1 * i1 + i2 * i2 - l * l) <= l)
                                        {
                                            switch (opt)
                                            {
                                                case "x": ChangeBlockValue(wbManager, h, i1 + pos3.Y, i2 + pos3.Z, hightLens[h][l]); break;
                                                case "y": ChangeBlockValue(wbManager, i1 + pos3.X, h, i2 + pos3.Z, hightLens[h][l]); break;
                                                case "z": ChangeBlockValue(wbManager, i1 + pos3.X, i2 + pos3.Y, h, hightLens[h][l]); break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        Point3 minPoint = new Point3(pos3.X - maxLength - 1, 0, pos3.Z - maxLength - 1);
                        Point3 maxPoint = new Point3(pos3.X + maxLength + 1, 0, pos3.Z + maxLength + 1);
                        PlaceReprocess(wbManager, commandData, true, minPoint, maxPoint);
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("moveblock", delegate (CommandData commandData)     //使方块运动
            {
                //moveblock type:default/dig/limit pos1:0,0,0 pos2:1,1,1 vec3:5,5,5 v:50
                Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                int v = (int)commandData.GetValue("v");
                string movingBlockId = string.Empty;
                switch (commandData.Type)
                {
                    case "default": movingBlockId = "moveblock$default"; break;
                    case "dig": movingBlockId = "moveblock$dig"; break;
                    case "limit": movingBlockId = "moveblock$limit"; break;
                }
                CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                List<MovingBlock> list = new List<MovingBlock>();
                cubeArea.Ergodic(delegate
                {
                    list.Add(new MovingBlock
                    {
                        Value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z),
                        Offset = cubeArea.Current - cubeArea.MinPoint
                    });
                    return false;
                });
                Vector3 vector1 = new Vector3(cubeArea.MinPoint.X, cubeArea.MinPoint.Y, cubeArea.MinPoint.Z);
                Vector3 vector2 = vector1 + vec3;
                SubsystemMovingBlocks subsystemMovingBlocks = base.Project.FindSubsystem<SubsystemMovingBlocks>();
                IMovingBlockSet movingBlockSet = subsystemMovingBlocks.AddMovingBlockSet(vector1, vector2, v / 10f, 0f, 0f, new Vector2(1, 1), list, movingBlockId, arpos[0], testCollision: true);
                if (movingBlockSet != null)
                {
                    foreach (MovingBlock movingBlock in list)
                    {
                        m_subsystemTerrain.ChangeCell(cubeArea.MinPoint.X + movingBlock.Offset.X, cubeArea.MinPoint.Y + movingBlock.Offset.Y, cubeArea.MinPoint.Z + movingBlock.Offset.Z, 0);
                    }
                }
                else
                {
                    ShowSubmitTips("运动方块添加失败，发生未知错误");
                    return SubmitResult.Fail;
                }
                return SubmitResult.Success;
            });
            AddFunction("moveset", delegate (CommandData commandData)       //运动设计玩法
            {
                string n = (string)commandData.GetValue("n");
                //moveset type:default pos1:0,0,0 pos2:1,1,1 pos3:2,2,2 opt:+x n:小车车
                if (commandData.Type == "default")
                {
                    string opt = (string)commandData.GetValue("opt");
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    Point3 pos3 = GetOnePoint("pos3", commandData);
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    string[] chars = new string[] { "$", "|", ":", "@", "&" };
                    foreach (string c in chars)
                    {
                        if (n.Contains(c))
                        {
                            ShowSubmitTips("运动设计名称不能包含特殊符号且不能为纯数字");
                            return SubmitResult.Fail;
                        }
                    }
                    if (GetMovingBlockTagLine(n) != null || ExistWaitMoveSet(n))
                    {
                        ShowSubmitTips("名为" + n + "的运动方块设计已存在");
                        return SubmitResult.Fail;
                    }
                    string tag = SetMovingBlockTagLine(n, opt, pos3 - cubeArea.MinPoint);
                    List<MovingBlock> list = new List<MovingBlock>();
                    cubeArea.Ergodic(delegate
                    {
                        int value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                        int id = Terrain.ExtractContents(value);
                        GetMoveEntityBlocks(tag, id, cubeArea.Current, cubeArea.Current - cubeArea.MinPoint);
                        list.Add(new MovingBlock
                        {
                            Value = value,
                            Offset = cubeArea.Current - cubeArea.MinPoint
                        });
                        return false;
                    });
                    Vector3 vector = new Vector3(cubeArea.MinPoint);
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.AddMovingBlockSet(vector, vector, 0f, 0f, 0f, new Vector2(1, 1), list, "moveset", tag, true);
                    if (movingBlockSet != null)
                    {
                        foreach (MovingBlock movingBlock in list)
                        {
                            m_subsystemTerrain.ChangeCell(cubeArea.MinPoint.X + movingBlock.Offset.X, cubeArea.MinPoint.Y + movingBlock.Offset.Y, cubeArea.MinPoint.Z + movingBlock.Offset.Z, 0);
                        }
                    }
                    else
                    {
                        ShowSubmitTips("名为" + n + "的运动方块设计添加失败，发生未知错误");
                        return SubmitResult.Fail;
                    }
                }
                //moveset type:append pos1:0,0,0 pos2:1,1,1 n:小车车
                else if (commandData.Type == "append")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    string tag = GetMovingBlockTagLine(n);
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            movingBlockSet = WaitMoveSetTurnToWork(tag, value);
                        }
                        else goto MovingSetNoFound;
                    }
                    List<MovingBlock> list = new List<MovingBlock>();
                    cubeArea.Ergodic(delegate
                    {
                        int cellValue = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                        movingBlockSet.SetBlock(cubeArea.Current - new Point3(movingBlockSet.Position), cellValue);
                        m_subsystemTerrain.ChangeCell(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z, 0);
                        return false;
                    });
                }
                //moveset type:move vec3:5,5,5 n:小车车 v:50 con:false
                else if (commandData.Type == "move")
                {
                    int v = (int)commandData.GetValue("v");
                    string tag = GetMovingBlockTagLine(n);
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    bool con = (bool)commandData.GetValue("con");
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            movingBlockSet = WaitMoveSetTurnToWork(tag, value);
                        }
                        else goto MovingSetNoFound;
                    }
                    MovingBlockTag movingBlockTag = FindMovingBlockTag(n);
                    if (con)
                    {
                        switch (movingBlockTag.Face)
                        {
                            case CoordDirection.NX: vec3 = new Vector3(-vec3.X, vec3.Y, -vec3.Z); break;
                            case CoordDirection.PZ: vec3 = new Vector3(-vec3.Z, vec3.Y, vec3.X); break;
                            case CoordDirection.NZ: vec3 = new Vector3(vec3.Z, vec3.Y, -vec3.X); break;
                        }
                    }
                    try
                    {
                        m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                        Vector3 targetPos = movingBlockSet.Position + vec3;
                        ((SubsystemMovingBlocks.MovingBlockSet)movingBlockSet).Stop = false;
                        m_subsystemMovingBlocks.AddMovingBlockSet(movingBlockSet.Position, targetPos, v / 10f, 0f, 0f, new Vector2(1, 1), movingBlockSet.Blocks, "moveset", tag, true);
                    }
                    catch
                    {
                        ShowSubmitTips("名为" + n + "的运动方块移动失败，发生未知错误");
                        return SubmitResult.Fail;
                    }
                }
                //moveset type:turn opt:left n:小车车
                else if (commandData.Type == "turn")
                {
                    string opt = (string)commandData.GetValue("opt");
                    string tag = GetMovingBlockTagLine(n);
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            movingBlockSet = WaitMoveSetTurnToWork(tag, value);
                        }
                        else goto MovingSetNoFound;
                    }
                    MovingBlockTag movingBlockTag = FindMovingBlockTag(n);
                    try
                    {
                        Point3 minPoint = new Point3((int)MathUtils.Round(movingBlockSet.Position.X), (int)MathUtils.Round(movingBlockSet.Position.Y), (int)MathUtils.Round(movingBlockSet.Position.Z));
                        Point3 maxPoint = Point3.Zero;
                        m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                        foreach (MovingBlock movingBlock in movingBlockSet.Blocks)
                        {
                            maxPoint = minPoint + movingBlock.Offset;
                            m_subsystemTerrain.ChangeCell(maxPoint.X, maxPoint.Y, maxPoint.Z, movingBlock.Value);
                        }
                        SetMoveEntityBlocks(movingBlockSet);
                        string angle;
                        int angleIndex = 0;
                        switch (opt)
                        {
                            case "back": angle = "+180"; angleIndex = 2; break;
                            case "left": angle = "+270"; angleIndex = 3; break;
                            case "right": angle = "+90"; angleIndex = 1; break;
                            default: return SubmitResult.Fail;
                        }
                        CopyBlockManager copyBlockManager = new CopyBlockManager(this, null, minPoint, maxPoint);
                        copyBlockManager.ClearBlockArea(true);
                        copyBlockManager.RotateCopy(movingBlockTag.Axis + minPoint, "+y", angle, true);
                        Point3 completePoint = copyBlockManager.GetRotatePoint(copyBlockManager.CubeArea.MinPoint, movingBlockTag.Axis + minPoint, "+y", angle);
                        Point3 completePoint2 = copyBlockManager.GetRotatePoint(copyBlockManager.CubeArea.MaxPoint, movingBlockTag.Axis + minPoint, "+y", angle);
                        string face = "+x";
                        switch (movingBlockTag.Face)
                        {
                            case CoordDirection.PX: face = "+x"; break;
                            case CoordDirection.NX: face = "-x"; break;
                            case CoordDirection.PZ: face = "+z"; break;
                            case CoordDirection.NZ: face = "-z"; break;
                        }
                        string[] faces = new string[4] { "+x", "+z", "-x", "-z" };
                        for (int a = 0; a < faces.Length; a++)
                        {
                            if (face == faces[a])
                            {
                                face = faces[(a + angleIndex) % faces.Length];
                                break;
                            }
                        }
                        CubeArea cubeArea = new CubeArea(completePoint, completePoint2);
                        tag = SetMovingBlockTagLine(movingBlockTag.Name, face, movingBlockTag.Axis + minPoint - cubeArea.MinPoint);
                        List<MovingBlock> list = new List<MovingBlock>();
                        cubeArea.Ergodic(delegate
                        {
                            int value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                            int id = Terrain.ExtractContents(value);
                            GetMoveEntityBlocks(tag, id, cubeArea.Current, cubeArea.Current - cubeArea.MinPoint);
                            list.Add(new MovingBlock
                            {
                                Value = value,
                                Offset = cubeArea.Current - cubeArea.MinPoint
                            });
                            return false;
                        });
                        Vector3 vector = new Vector3(cubeArea.MinPoint);
                        Vector3 velocity = ((SubsystemMovingBlocks.MovingBlockSet)movingBlockSet).TargetPosition - ((SubsystemMovingBlocks.MovingBlockSet)movingBlockSet).Position;
                        switch (opt)
                        {
                            case "back": velocity = new Vector3(-velocity.X, velocity.Y, -velocity.Z); break;
                            case "left": velocity = new Vector3(velocity.Z, velocity.Y, -velocity.X); break;
                            case "right": velocity = new Vector3(-velocity.Z, velocity.Y, velocity.X); break;
                            default: velocity = Vector3.Zero; break;
                        }
                        movingBlockSet = m_subsystemMovingBlocks.AddMovingBlockSet(vector, vector + velocity, ((SubsystemMovingBlocks.MovingBlockSet)movingBlockSet).Speed, 0f, 0f, new Vector2(1, 1), list, "moveset", tag, true);
                        if (movingBlockSet != null)
                        {
                            foreach (MovingBlock movingBlock in list)
                            {
                                m_subsystemTerrain.ChangeCell(cubeArea.MinPoint.X + movingBlock.Offset.X, cubeArea.MinPoint.Y + movingBlock.Offset.Y, cubeArea.MinPoint.Z + movingBlock.Offset.Z, 0);
                            }
                        }
                    }
                    catch
                    {
                        ShowSubmitTips("名为" + n + "的运动方块转弯失败，发生未知错误");
                        return SubmitResult.Fail;
                    }
                }
                //moveset type:pause n:小车车
                else if (commandData.Type == "pause")
                {
                    string tag = GetMovingBlockTagLine(n);
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            movingBlockSet = WaitMoveSetTurnToWork(tag, value);
                        }
                        else goto MovingSetNoFound;
                    }
                    try
                    {
                        movingBlockSet.Stop();
                        m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                        m_subsystemMovingBlocks.AddMovingBlockSet(movingBlockSet.Position, movingBlockSet.Position, 0f, 0f, 0f, new Vector2(1, 1), movingBlockSet.Blocks, "moveset", tag, true);
                    }
                    catch
                    {
                        ShowSubmitTips("名为" + n + "的运动方块移除失败，发生未知错误");
                        return SubmitResult.Fail;
                    }
                }
                //moveset type:stop n:小车车
                else if (commandData.Type == "stop")
                {
                    string tag = GetMovingBlockTagLine(n);
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            return SubmitResult.Success;
                        }
                        else goto MovingSetNoFound;
                    }
                    try
                    {
                        movingBlockSet.Stop();
                        m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                        m_waitingMoveSets[tag] = new List<Point3>();
                        foreach (MovingBlock movingBlock in movingBlockSet.Blocks)
                        {
                            Point3 point = new Point3((int)MathUtils.Round(movingBlockSet.Position.X), (int)MathUtils.Round(movingBlockSet.Position.Y), (int)MathUtils.Round(movingBlockSet.Position.Z)) + movingBlock.Offset;
                            m_waitingMoveSets[tag].Add(point);
                            m_subsystemTerrain.ChangeCell(point.X, point.Y, point.Z, movingBlock.Value);
                        }
                        SetMoveEntityBlocks(movingBlockSet);
                    }
                    catch
                    {
                        ShowSubmitTips("名为" + n + "的运动方块无法转为普通方块，发生未知错误");
                        return SubmitResult.Fail;
                    }
                }
                //moveset type:remove n:小车车
                else if (commandData.Type == "remove")
                {
                    string tag = GetMovingBlockTagLine(n);
                    IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            m_waitingMoveSets.Remove(tag);
                            return SubmitResult.Success;
                        }
                        else goto MovingSetNoFound;
                    }
                    try
                    {
                        m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                        foreach (MovingBlock movingBlock in movingBlockSet.Blocks)
                        {
                            Point3 point = new Point3((int)MathUtils.Round(movingBlockSet.Position.X), (int)MathUtils.Round(movingBlockSet.Position.Y), (int)MathUtils.Round(movingBlockSet.Position.Z)) + movingBlock.Offset;
                            m_subsystemTerrain.ChangeCell(point.X, point.Y, point.Z, movingBlock.Value);
                        }
                        SetMoveEntityBlocks(movingBlockSet);
                    }
                    catch
                    {
                        ShowSubmitTips("名为" + n + "的运动方块移除失败，发生未知错误");
                        return SubmitResult.Fail;
                    }
                }
                //moveset type:removeall
                else if (commandData.Type == "removeall")
                {
                    List<IMovingBlockSet> movingBlockSetList = new List<IMovingBlockSet>();
                    foreach (IMovingBlockSet movingBlockSet in m_subsystemMovingBlocks.MovingBlockSets)
                    {
                        movingBlockSetList.Add(movingBlockSet);
                    }
                    foreach (IMovingBlockSet movingBlockSet in movingBlockSetList)
                    {
                        if (movingBlockSet.Id == "moveset")
                        {
                            m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                            foreach (MovingBlock movingBlock in movingBlockSet.Blocks)
                            {
                                Point3 point = new Point3((int)MathUtils.Round(movingBlockSet.Position.X), (int)MathUtils.Round(movingBlockSet.Position.Y), (int)MathUtils.Round(movingBlockSet.Position.Z)) + movingBlock.Offset;
                                m_subsystemTerrain.ChangeCell(point.X, point.Y, point.Z, movingBlock.Value);
                            }
                            SetMoveEntityBlocks(movingBlockSet);
                        }
                    }
                    m_waitingMoveSets.Clear();
                }
                return SubmitResult.Success;
                MovingSetNoFound:
                {
                    ShowEditedTips("提示:名为" + n + "的运动方块设计不存在");
                    return SubmitResult.Fail;
                }
            });
            AddFunction("furniture", delegate (CommandData commandData)     //家具功能延伸
            {
                //furniture type:default pos:0,0,0
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    CellFace start = new CellFace(pos.X, pos.Y, pos.Z, 4);
                    m_subsystemFurnitureBlockBehavior.ScanDesign(start, Vector3.Zero, m_componentPlayer.ComponentMiner);
                }
                //furniture type:hammer pos1:0,0,0 pos2:1,1,1 pos3:2,2,2 v1:16 v2:0
                else if (commandData.Type == "hammer")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    Point3 pos3 = GetOnePoint("pos3", commandData);
                    int v1 = (int)commandData.GetValue("v1");
                    int v2 = (int)commandData.GetValue("v2");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    int division = v1;
                    int rotate = v2;
                    cube.Ergodic(division, 0.1f, delegate (Point3 origin, Point3 coord, Point3 finalCoord)
                    {
                        List<int> values = new List<int>();
                        int l = 0;
                        bool pass = false;
                        for (int i = 0; i < division; i++)
                        {
                            for (int j = 0; j < division; j++)
                            {
                                for (int k = 0; k < division; k++)
                                {
                                    int value = GetLimitValue(origin.X + k, origin.Y + j, origin.Z + i);
                                    values.Add(value);
                                    pass |= (value != 0);
                                    l++;
                                }
                            }
                        }
                        Point3 p = new Point3(pos3.X + coord.X, pos3.Y + coord.Y, pos3.Z + coord.Z);
                        switch (rotate)
                        {
                            case 1: p = new Point3(pos3.X - coord.Z, pos3.Y + coord.Y, pos3.Z + coord.X); break;
                            case 2: p = new Point3(pos3.X - coord.X, pos3.Y + coord.Y, pos3.Z - coord.Z); break;
                            case 3: p = new Point3(pos3.X + coord.Z, pos3.Y + coord.Y, pos3.Z - coord.X); break;
                            default: break;
                        }
                        if (pass)
                        {
                            try
                            {
                                FurnitureDesign design = new FurnitureDesign(m_subsystemTerrain);
                                design.SetValues(division, values.ToArray());
                                design.Rotate(1, rotate);
                                FurnitureDesign resultDesign = m_subsystemFurnitureBlockBehavior.TryAddDesign(design);
                                int result = Terrain.MakeBlockValue(227, 0, FurnitureBlock.SetDesignIndex(0, resultDesign.Index, resultDesign.ShadowStrengthFactor, resultDesign.IsLightEmitter));
                                m_subsystemPickables.AddPickable(result, 1, new Vector3(commandData.Position) + new Vector3(0.5f, 1f, 0.5f), null, null);
                                m_subsystemTerrain.ChangeCell(p.X, p.Y, p.Z, result);
                            }
                            catch
                            {
                                ShowSubmitTips(string.Format("处理区域({0})-({1})时发生未知错误", origin.ToString(), (origin + new Point3(division)).ToString()));
                                m_subsystemTerrain.ChangeCell(p.X, p.Y, p.Z, 0);
                            }
                        }
                        else
                        {
                            m_subsystemTerrain.ChangeCell(p.X, p.Y, p.Z, 0);
                        }
                    });
                }
                //furniture type:slotreduct fid:0 pos:5,5,5
                else if (commandData.Type == "slotreduct")
                {
                    int fid = (int)commandData.GetValue("fid");
                    Point3 pos = GetOnePoint("pos", commandData);
                    FurnitureDesign design = m_subsystemFurnitureBlockBehavior.GetDesign(fid);
                    if (design == null)
                    {
                        ShowSubmitTips("找不到对应家具");
                        return SubmitResult.Fail;
                    }
                    int l = 0;
                    for (int i = 0; i < design.Resolution; i++)
                    {
                        for (int j = 0; j < design.Resolution; j++)
                        {
                            for (int k = 0; k < design.Resolution; k++)
                            {
                                m_subsystemTerrain.ChangeCell(pos.X - i, pos.Y + j, pos.Z + k, design.m_values[l++]);
                            }
                        }
                    }
                }
                //furniture type:posreduct pos1:0,0,0 pos2:1,1,1 pos3:2,2,2
                else if (commandData.Type == "posreduct")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    Point3 pos3 = GetOnePoint("pos3", commandData);
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    cubeArea.Ergodic(delegate
                    {
                        int value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                        if (Terrain.ExtractContents(value) == 227)
                        {
                            int data = Terrain.ExtractData(value);
                            int fid = FurnitureBlock.GetDesignIndex(data);
                            int rotate = FurnitureBlock.GetRotation(data);
                            FurnitureDesign design = m_subsystemFurnitureBlockBehavior.GetDesign(fid).Clone();
                            design.Rotate(1, rotate);
                            if (rotate == 1 || rotate == 3)
                            {
                                design.Mirror(0);
                            }
                            int l = 0;
                            Point3 point = (cubeArea.Current - cubeArea.MinPoint) * design.Resolution + pos3;
                            Point3 point2 = Point3.Zero;
                            for (int i = 0; i < design.Resolution; i++)
                            {
                                for (int j = 0; j < design.Resolution; j++)
                                {
                                    for (int k = 0; k < design.Resolution; k++)
                                    {
                                        switch (rotate)
                                        {
                                            case 0: point2 = new Point3(k, j, i); break;
                                            case 1: point2 = new Point3(design.Resolution - k, j, i); break;
                                            case 2: point2 = new Point3(k, j, i); break;
                                            case 3: point2 = new Point3(design.Resolution - k, j, i); break;
                                            default: break;
                                        }
                                        m_subsystemTerrain.ChangeCell(point.X + point2.X, point.Y + point2.Y, point.Z + point2.Z, design.m_values[l++]);
                                    }
                                }
                            }
                        }
                        return false;
                    });
                }
                //furniture type:replace pos1:0,0,0 pos2:1,1,1 id1:46 id2:126
                else if (commandData.Type == "replace")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id1 = (int)commandData.GetValue("id1");
                    int id2 = (int)commandData.GetValue("id2");
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    cubeArea.Ergodic(delegate
                    {
                        int value = m_subsystemTerrain.Terrain.GetCellValue(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z);
                        int id = Terrain.ExtractContents(value);
                        int data = Terrain.ExtractData(value);
                        if (id == 227)
                        {
                            int fid = FurnitureBlock.GetDesignIndex(data);
                            FurnitureDesign design = m_subsystemFurnitureBlockBehavior.GetDesign(fid);
                            if (design != null)
                            {
                                List<FurnitureDesign> list = design.CloneChain();
                                foreach (FurnitureDesign item in list)
                                {
                                    int[] array = new int[design.m_values.Length];
                                    for (int l = 0; l < design.m_values.Length; l++)
                                    {
                                        int designvalue = Terrain.ReplaceLight(design.m_values[l], 0);
                                        if (designvalue == id1)
                                        {
                                            array[l] = id2;
                                        }
                                        else
                                        {
                                            array[l] = design.m_values[l];
                                        }
                                    }
                                    item.SetValues(design.m_resolution, array);
                                    FurnitureDesign design2 = m_subsystemFurnitureBlockBehavior.TryAddDesignChain(list[0], garbageCollectIfNeeded: true);
                                    if (design2 != null)
                                    {
                                        int data2 = FurnitureBlock.SetDesignIndex(data, design2.Index, design2.ShadowStrengthFactor, design2.IsLightEmitter);
                                        int value2 = Terrain.ReplaceData(value, data2);
                                        m_subsystemTerrain.ChangeCell(cubeArea.Current.X, cubeArea.Current.Y, cubeArea.Current.Z, value2);
                                    }
                                }
                            }
                        }
                        return false;
                    });
                }
                //furniture type:link+x/wire+x pos:0,0,0 con:true
                else if (commandData.Type == "link+x" || commandData.Type == "wire+x")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    bool con = (bool)commandData.GetValue("con");
                    bool isLinkWire = (commandData.Type == "wire+x");
                    List<int> fidList = new List<int>();
                    List<FurnitureDesign> designList = new List<FurnitureDesign>();
                    int l = 0;
                    while (l < 1024)
                    {
                        int value = m_subsystemTerrain.Terrain.GetCellValue(pos.X + (l++), pos.Y, pos.Z);
                        if (Terrain.ExtractContents(value) == 227)
                        {
                            fidList.Add(FurnitureBlock.GetDesignIndex(Terrain.ExtractData(value)));
                        }
                        else break;
                    }
                    if (fidList.Count < 2)
                    {
                        ShowSubmitTips("家具数量少于2，无法链接");
                        return SubmitResult.Fail;
                    }
                    foreach (int fid in fidList)
                    {
                        FurnitureDesign design = m_subsystemFurnitureBlockBehavior.GetDesign(fid);
                        if (design != null)
                        {
                            if (con && design.LinkedDesign != null)
                            {
                                foreach (FurnitureDesign chainDesign in design.ListChain())
                                {
                                    designList.Add(chainDesign.Clone());
                                }
                            }
                            else
                            {
                                designList.Add(design.Clone());
                            }
                        }
                    }
                    for (int k = 0; k < designList.Count; k++)
                    {
                        designList[k].InteractionMode = isLinkWire ? FurnitureInteractionMode.ConnectedMultistate : FurnitureInteractionMode.Multistate;
                        designList[k].LinkedDesign = designList[(k + 1) % designList.Count];
                    }
                    FurnitureDesign resultDesign = m_subsystemFurnitureBlockBehavior.TryAddDesignChain(designList[0], garbageCollectIfNeeded: true);
                    if (resultDesign != null)
                    {
                        int resultValue = Terrain.MakeBlockValue(227, 0, FurnitureBlock.SetDesignIndex(0, resultDesign.Index, resultDesign.ShadowStrengthFactor, resultDesign.IsLightEmitter));
                        Vector3 postion = (commandData.Position == Point3.Zero) ? m_componentPlayer.ComponentBody.Position : new Vector3(commandData.Position);
                        m_subsystemPickables.AddPickable(resultValue, 1, postion + new Vector3(0.5f, 1f, 0.5f), null, null);
                    }
                }
                //furniture type:find fid:0
                else if (commandData.Type == "find")
                {
                    int fid = (int)commandData.GetValue("fid");
                    SubsystemSpawn subsystemSpawn = Project.FindSubsystem<SubsystemSpawn>();
                    Point2[] chunkPoints = subsystemSpawn.m_chunks.Keys.ToArray();
                    int l = 0;
                    float t = 0;
                    List<Point3> points = new List<Point3>();
                    foreach (Point2 p in subsystemSpawn.m_chunks.Keys)
                    {
                        Time.QueueTimeDelayedExecution(Time.RealTime + t, delegate
                        {
                            int cx = chunkPoints[l].X * 16;
                            int cz = chunkPoints[l].Y * 16;
                            m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.Aero);
                            CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                            commandCamera.m_position = new Vector3(cx, commandCamera.m_position.Y, cz);
                            ShowSubmitTips(string.Format("正在扫描区块({0})-({1}),进度:{2}/{3}", new Point3(cx, 0, cz).ToString(), new Point3(cx + 16, 255, cz + 16).ToString(), l, chunkPoints.Length - 1));
                        });
                        Time.QueueTimeDelayedExecution(Time.RealTime + t + 0.5f, delegate
                        {
                            TerrainChunk chunk = m_subsystemTerrain.Terrain.GetChunkAtCoords(chunkPoints[l].X, chunkPoints[l].Y);
                            for (int i = 0; i < 16; i++)
                            {
                                for (int j = 0; j < 16; j++)
                                {
                                    for (int k = 0; k < 256; k++)
                                    {
                                        int x = chunk.Origin.X + i;
                                        int y = k;
                                        int z = chunk.Origin.Y + j;
                                        int id = m_subsystemTerrain.Terrain.GetCellContents(x, y, z);
                                        if (id == 227)
                                        {
                                            int value = m_subsystemTerrain.Terrain.GetCellValue(x, y, z);
                                            if (fid == FurnitureBlock.GetDesignIndex(Terrain.ExtractData(value)))
                                            {
                                                points.Add(new Point3(x, y, z));
                                                ShowSubmitTips(string.Format("点({0})发现目标家具!", new Point3(x, y, z).ToString()));
                                            }
                                        }
                                    }
                                }
                            }
                            if (l == chunkPoints.Length - 1)
                            {
                                string line = "查找完毕,";
                                if (points.Count != 0)
                                {
                                    line += "查找结果已复制到剪切板:\n";
                                    foreach (Point3 p2 in points)
                                    {
                                        line += p2.ToString() + "  ";
                                    }
                                    ClipboardManager.ClipboardString = line;
                                }
                                else
                                {
                                    line += "未找到目标家具";
                                }
                                m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<FppCamera>();
                                ShowSubmitTips(line);
                            }
                            l++;
                        });
                        t += 0.6f;
                    }
                }
                //furniture type:remove
                else if (commandData.Type == "remove")
                {
                    for (int k = 0; k < m_subsystemFurnitureBlockBehavior.m_furnitureDesigns.Length; k++)
                    {
                        FurnitureDesign design = m_subsystemFurnitureBlockBehavior.m_furnitureDesigns[k];
                        if (design != null && design.FurnitureSet == null)
                        {
                            m_subsystemFurnitureBlockBehavior.m_furnitureDesigns[k] = null;
                        }
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("camera", delegate (CommandData commandData)        //设置玩家相机
            {
                //camera type:default pos:0,0,0 eyes:0,90 con:false
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    Point2 eyes = (Point2)commandData.GetValue("eyes");
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, con ? CommandCamera.CameraType.Lock : CommandCamera.CameraType.Aero);
                    CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                    commandCamera.m_position = new Vector3(pos);
                    commandCamera.m_direction = DataHandle.EyesToDirection(eyes);
                }
                //camera type:lock
                else if (commandData.Type == "lock")
                {
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.Lock);
                }
                //camera type:aero
                else if (commandData.Type == "aero")
                {
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.Aero);
                }
                //camera type:move vec3:5,5,5 v:10 con:false
                else if (commandData.Type == "move")
                {
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    int v = (int)commandData.GetValue("v");
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.MovePos);
                    CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                    commandCamera.m_targetPosition = vec3 + commandCamera.m_position;
                    commandCamera.m_speed = v / 10f;
                    commandCamera.m_skipToAero = !con;
                }
                //camera type:direct eyes:0,90 v:10 con:false
                else if (commandData.Type == "direct")
                {
                    Point2 eyes = (Point2)commandData.GetValue("eyes");
                    int v = (int)commandData.GetValue("v");
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.MoveDirect);
                    CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                    commandCamera.m_targetDirection = DataHandle.EyesToDirection(eyes);
                    commandCamera.m_speed = v / 10f;
                    commandCamera.m_skipToAero = !con;
                }
                //camera type:byo-fpp/byo-tpp/byo-orbit/byo-fixed
                else if (commandData.Type.StartsWith("byo"))
                {
                    switch (commandData.Type)
                    {
                        case "byo-fpp": m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<FppCamera>(true); break;
                        case "byo-tpp": m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<TppCamera>(true); break;
                        case "byo-orbit": m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<OrbitCamera>(true); break;
                        case "byo-fixed": m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<FixedCamera>(true); break;
                        default: break;
                    }
                }
                //camera type:relative vec3:0,0,0 vec2:0,90
                else if (commandData.Type == "relative")
                {
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.MoveWithPlayer);
                    CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                    commandCamera.m_relativePosition = vec3;
                    commandCamera.m_relativeAngle = new Point2((int)vec2.X, (int)vec2.Y);
                }
                else if (commandData.Type == "record")
                {
                    RecordManager.Recording = true;
                    RecordManager.Replaying = false;
                    RecordManager.FirstTime = (float)m_subsystemTime.GameTime;
                    RecordManager.ReplayTime = 0;
                    RecordManager.ActionIndex = 0;
                    RecordManager.StatsIndex = 0;
                    RecordManager.FirstPosition = m_componentPlayer.GameWidget.ActiveCamera.ViewPosition;
                    RecordManager.FirstDirection = m_componentPlayer.GameWidget.ActiveCamera.ViewDirection;
                    RecordManager.RecordPlayerActions.Clear();
                    RecordManager.RecordPlayerStats.Clear();
                    RecordManager.ChangeBlocks.Clear();
                }
                else if (commandData.Type == "replay")
                {
                    RecordManager.Recording = false;
                    RecordManager.Replaying = true;
                    foreach (var cb in RecordManager.ChangeBlocks.Keys)
                    {
                        m_subsystemTerrain.ChangeCell(cb.X, cb.Y, cb.Z, RecordManager.ChangeBlocks[cb]);
                    }
                    foreach (var p in m_subsystemPickables.Pickables)
                    {
                        p.ToRemove = true;
                    }
                    m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.Aero);
                    CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                    commandCamera.m_position = RecordManager.FirstPosition;
                    commandCamera.m_direction = RecordManager.FirstDirection;
                }
                return SubmitResult.Success;
            });
            AddFunction("gametime", delegate (CommandData commandData)      //更改游戏时间
            {
                //gametime type:default /*v:1024*/
                if (commandData.Type == "default")
                {
                    SubsystemTimeOfDay subsystemTimeOfDay = Project.FindSubsystem<SubsystemTimeOfDay>();
                    int day = (int)(subsystemTimeOfDay.TimeOfDay * 4096);
                    ShowSubmitTips(string.Format("当前游戏时间{0}/{1}", day, 4096));
                    //int v = (int)commandData.GetValue("v");
                    //SubsystemTimeOfDay subsystemTimeOfDay = Project.FindSubsystem<SubsystemTimeOfDay>();
                    //m_subsystemGameInfo.TotalElapsedGameTime = 0f;
                    //subsystemTimeOfDay.TimeOfDayOffset = (int)(subsystemTimeOfDay.TimeOfDayOffset + 0.30000001192092896 + 0.005) - 0.30000001192092896 + v / 4096f;
                }
                //gametime type:byo-dawn/byo-noon/byo-dusk/byo-night
                else if (commandData.Type.StartsWith("byo"))
                {
                    SubsystemTimeOfDay subsystemTimeOfDay = Project.FindSubsystem<SubsystemTimeOfDay>();
                    int type = 0;
                    switch (commandData.Type)
                    {
                        case "byo-dawn": type = 1; break;
                        case "byo-noon": type = 2; break;
                        case "byo-dusk": type = 3; break;
                        case "byo-night": type = 4; break;
                        default: break;
                    }
                    subsystemTimeOfDay.TimeOfDayOffset += MathUtils.Remainder(MathUtils.Remainder(0.25f * (float)type, 1f) - subsystemTimeOfDay.TimeOfDay, 1f); ;
                }
                //gametime type:accelerate v:5
                else if (commandData.Type == "accelerate")
                {
                    int v = (int)commandData.GetValue("v");
                    if (v == 10) v = 255;
                    Project.FindSubsystem<SubsystemTime>().GameTimeFactor = v;
                }
                //gametime type:slow v:5
                else if (commandData.Type == "slow")
                {
                    int v = (int)commandData.GetValue("v");
                    if (v == 10) v = 1000;
                    Project.FindSubsystem<SubsystemTime>().GameTimeFactor = 1f / v;
                }
                return SubmitResult.Success;
            });
            AddFunction("gamemode", delegate (CommandData commandData)      //更改游戏模式
            {
                //gamemode type:default/creative/harmless/challenge/adventure/cruel
                GameMode gameMode = GameMode.Creative;
                if (commandData.Type != "cruel")
                {
                    switch (commandData.Type)
                    {
                        case "default": gameMode = m_gameMode; break;
                        case "creative": gameMode = GameMode.Creative; break;
                        case "harmless": gameMode = GameMode.Harmless; break;
                        case "challenge": gameMode = GameMode.Challenging; break;
                        case "adventure": gameMode = GameMode.Adventure; break;
                        default: break;
                    }
                }
                else
                {
                    string text = (string)commandData.GetValue("text");
                    if (text == "LEURC")
                    {
                        gameMode = GameMode.Cruel;
                    }
                    else
                    {
                        ShowSubmitTips("密码错误，请重新输入");
                        return SubmitResult.Fail;
                    }
                }
                m_subsystemGameInfo.WorldSettings.GameMode = gameMode;
                WorldInfo worldInfo = GameManager.WorldInfo;
                GameManager.SaveProject(true, true);
                GameManager.DisposeProject();
                ScreensManager.SwitchScreen("GameLoading", worldInfo, null);
                return SubmitResult.Success;
            });
            AddFunction("settings", delegate (CommandData commandData)      //更改游戏设置
            {
                //settings type:default
                if (commandData.Type == "default")
                {
                    ScreensManager.SwitchScreen("Settings");
                }
                //settings type:visibility v:500
                else if (commandData.Type == "visibility")
                {
                    int v = (int)commandData.GetValue("v");
                    if (v < 0)
                    {
                        ShowSubmitTips("游戏视距不能小于0");
                        return SubmitResult.Fail;
                    }
                    SettingsManager.VisibilityRange = v;
                }
                //settings type:brightness v:10
                else if (commandData.Type == "brightness")
                {
                    int v = (int)commandData.GetValue("v");
                    SettingsManager.Brightness = v / 100f;
                }
                //settings type:skymode opt:disable
                else if (commandData.Type == "skymode")
                {
                    string opt = (string)commandData.GetValue("opt");
                    switch (opt)
                    {
                        case "full": SettingsManager.SkyRenderingMode = SkyRenderingMode.Full; break;
                        case "nocloud": SettingsManager.SkyRenderingMode = SkyRenderingMode.NoClouds; break;
                        case "disable": SettingsManager.SkyRenderingMode = SkyRenderingMode.Disabled; break;
                        default: ShowSubmitTips("指令settings类型skymode找不到天空模式：" + opt); return SubmitResult.Fail;
                    }
                }
                //settings type:vol-sound/vol-music/sen-move/sen-look v:5
                else if (commandData.Type.StartsWith("vol-") || commandData.Type.StartsWith("sen-"))
                {
                    int v = (int)commandData.GetValue("v");
                    switch (commandData.Type)
                    {
                        case "vol-sound": SettingsManager.SoundsVolume = v / 10f; break;
                        case "vol-music": SettingsManager.MusicVolume = v / 10f; break;
                        case "sen-move": SettingsManager.MoveSensitivity = v / 10f; break;
                        case "sen-look": SettingsManager.LookSensitivity = v / 10f; break;
                        default: break;
                    }
                }
                //settings type:advsurvive con:true
                else if (commandData.Type == "advsurvive")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_subsystemGameInfo.WorldSettings.AreAdventureSurvivalMechanicsEnabled = con;
                }
                //settings type:livingmode con:true
                else if (commandData.Type == "livingmode")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_subsystemGameInfo.WorldSettings.EnvironmentBehaviorMode = con ? EnvironmentBehaviorMode.Living : EnvironmentBehaviorMode.Static;
                }
                //settings type:weathereffect con:true
                else if (commandData.Type == "weathereffect")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_subsystemGameInfo.WorldSettings.AreWeatherEffectsEnabled = con;
                }
                //settings type:daymode opt:day
                else if (commandData.Type == "daymode")
                {
                    string opt = (string)commandData.GetValue("opt");
                    TimeOfDayMode timeOfDayMode = TimeOfDayMode.Day;
                    switch (opt)
                    {
                        case "day": timeOfDayMode = TimeOfDayMode.Day; break;
                        case "night": timeOfDayMode = TimeOfDayMode.Night; break;
                        case "change": timeOfDayMode = TimeOfDayMode.Changing; break;
                        case "sunrise": timeOfDayMode = TimeOfDayMode.Sunrise; break;
                        case "sunset": timeOfDayMode = TimeOfDayMode.Sunset; break;
                        default: ShowSubmitTips("指令settings类型daymode找不到时间模式：" + opt); return SubmitResult.Fail;
                    }
                    m_subsystemGameInfo.WorldSettings.TimeOfDayMode = timeOfDayMode;
                }
                return SubmitResult.Success;
            });
            AddFunction("shapeshifter", delegate (CommandData commandData)  //控制狼人形态
            {
                //shapeshifter type:default con:true
                bool con = (bool)commandData.GetValue("con");
                m_shapeshifter = con;
                string name1 = con ? "Wolf_Gray" : "Werewolf";
                string name2 = con ? "Werewolf" : "Wolf_Gray";
                ErgodicBody(name1, delegate (ComponentBody body)
                {
                    ComponentShapeshifter componentShapeshifter = body.Entity.FindComponent<ComponentShapeshifter>();
                    if (componentShapeshifter != null)
                    {
                        componentShapeshifter.IsEnabled = true;
                        componentShapeshifter.ShapeshiftTo(name2);
                    }
                    return false;
                });
                Time.QueueTimeDelayedExecution(Time.RealTime + 5f, delegate
                {
                    ErgodicBody(name2, delegate (ComponentBody body)
                    {
                        ComponentShapeshifter componentShapeshifter = body.Entity.FindComponent<ComponentShapeshifter>();
                        if (componentShapeshifter != null) componentShapeshifter.IsEnabled = !con;
                        return false;
                    });
                });
                return SubmitResult.Success;
            });
            AddFunction("lockscreen", delegate (CommandData commandData)    //控制屏幕状态
            {
                //lockscreen type:default con:true
                bool con = (bool)commandData.GetValue("con");
                m_componentPlayer.ComponentLocomotion.LookSpeed = con ? 0.00000008f : 8;
                m_componentPlayer.ComponentLocomotion.TurnSpeed = con ? 0.00000008f : 8;
                return SubmitResult.Success;
            });
            AddFunction("deathscreen", delegate (CommandData commandData)   //玩家死亡动态
            {
                //deathscreen type:default con:true
                bool con = (bool)commandData.GetValue("con");
                if (con)
                {
                    m_enterDeathScreen = true;
                    m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<DeathCamera>();
                }
                else
                {
                    m_enterDeathScreen = false;
                    m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<FppCamera>();
                }
                return SubmitResult.Success;
            });
            AddFunction("blockfirm", delegate (CommandData commandData)     //方块不可破坏
            {
                //blockfirm type:default con:true
                if (commandData.Type == "default")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_firmAllBlocks = con;
                    if (con)
                    {
                        SubsystemCommandExt.BlockDataChange = true;
                        for (int i = 1; i < BlocksManager.Blocks.Length; i++)
                        {
                            try
                            {
                                Block block = BlocksManager.Blocks[i];
                                block.DigResilience = float.PositiveInfinity;
                                block.ExplosionResilience = float.PositiveInfinity;
                                block.ProjectileResilience = float.PositiveInfinity;
                                block.FireDuration = 0;
                                block.DefaultDropCount = 0;
                                block.DefaultExperienceCount = 0;
                            }
                            catch
                            {
                            }
                        }
                    }
                    else
                    {
                        SubsystemCommandExt.BlockDataChange = false;
                        foreach (ModEntity modEntity in ModsManager.ModList)
                        {
                            modEntity.LoadBlocksData();
                        }
                    }
                }
                //blockfirm type:limit id:46 con:true
                else if (commandData.Type == "limit")
                {
                    int id = (int)commandData.GetValue("id");
                    bool con = (bool)commandData.GetValue("con");
                    id = Terrain.ExtractContents(id);
                    if (con)
                    {
                        SetFirmBlocks(id, true, null);
                        if (!m_firmBlockList.Contains(id)) m_firmBlockList.Add(id);
                    }
                    else
                    {
                        if (OriginFirmBlockList.TryGetValue(id, out float[] value))
                        {
                            SetFirmBlocks(id, false, value);
                        }
                        if (m_firmBlockList.Contains(id)) m_firmBlockList.Remove(id);
                    }
                }
                //blockfirm type:nosqueeze con:true
                else if (commandData.Type == "nosqueeze")
                {
                    bool con = (bool)commandData.GetValue("con");
                    m_componentPlayer.ComponentMiner.m_canSqueezeBlock = !con;
                }
                return SubmitResult.Success;
            });
            AddFunction("getcell", delegate (CommandData commandData)       //获取方块文件
            {
                //getcell type:default/global/chunk pos1:0,0,0 pos2:1,1,1 f:小丑房.txt
                Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                string f = (string)commandData.GetValue("f");
                bool isDefault = (commandData.Type == "default");
                bool isGlobal = (commandData.Type == "global");
                bool isChunk = (commandData.Type == "chunk");
                CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                Stream stream = GetCommandFileStream(f, OpenFileMode.CreateOrOpen);
                StreamWriter streamwriter = new StreamWriter(stream);
                if (isDefault || isGlobal)
                {
                    cube.Ergodic(delegate
                    {
                        int x = isGlobal ? cube.Current.X : cube.Current.X - cube.MinPoint.X;
                        int y = isGlobal ? cube.Current.Y : cube.Current.Y - cube.MinPoint.Y;
                        int z = isGlobal ? cube.Current.Z : cube.Current.Z - cube.MinPoint.Z;
                        int value = m_subsystemTerrain.Terrain.GetCellValue(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        if (Terrain.ExtractContents(value) != 0)
                        {
                            string cell = string.Format("{0},{1},{2},{3}", x, y, z, value);
                            streamwriter.WriteLine(cell);
                        }
                        return false;
                    });
                    streamwriter.Flush();
                    stream.Dispose();
                    ShowSubmitTips("方块文件已生成，路径：\n" + DataHandle.GetCommandResPathName(f));
                }
                else if (isChunk)
                {
                    cube.ErgodicByChunk(3f, 0.1f, delegate (Point3 origin, Point2 coord, Point2 finalCoord)
                    {
                        m_componentPlayer.GameWidget.ActiveCamera = new CommandCamera(m_componentPlayer.GameWidget, CommandCamera.CameraType.Aero);
                        CommandCamera commandCamera = m_componentPlayer.GameWidget.ActiveCamera as CommandCamera;
                        commandCamera.m_position = new Vector3(origin) + new Vector3(0, 100, 0);
                        if (coord.X == -1 && coord.Y == -1)
                        {
                            ShowSubmitTips("方块文件正在生成，请耐心等候");
                        }
                        else
                        {
                            string chunk = string.Format("#CHUNK:{0},{1}", coord.X, coord.Y);
                            streamwriter.WriteLine(chunk);
                            for (int i = 0; i < 16; i++)
                            {
                                for (int j = 0; j < cube.LengthY; j++)
                                {
                                    for (int k = 0; k < 16; k++)
                                    {
                                        Point3 p = new Point3(origin.X + i, origin.Y + j, origin.Z + k);
                                        int value = m_subsystemTerrain.Terrain.GetCellValue(p.X, p.Y, p.Z);
                                        if (Terrain.ExtractContents(value) != 0)
                                        {
                                            string cell = string.Format("{0},{1},{2},{3}", p.X, p.Y, p.Z, value);
                                            streamwriter.WriteLine(cell);
                                        }
                                    }
                                }
                            }
                            streamwriter.WriteLine("###\n");
                            ShowSubmitTips(string.Format("区块({0})-({1})的方块信息已生成完毕", origin.ToString(), (origin + new Point3(16, cube.LengthY, 16)).ToString()));
                            if (coord.X == finalCoord.X && coord.Y == finalCoord.Y)
                            {
                                streamwriter.Flush();
                                stream.Dispose();
                                m_componentPlayer.GameWidget.ActiveCamera = m_componentPlayer.GameWidget.FindCamera<FppCamera>(true);
                                ShowSubmitTips("方块文件已生成，路径：\n" + DataHandle.GetCommandResPathName(f));
                            }
                        }
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("memorydata", delegate (CommandData commandData)    //转换填装m板数据
            {
                //memorydata type:default pos:0,0,0 text:123456
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    string text = (string)commandData.GetValue("text");
                    SubsystemMemoryBankBlockBehavior memoryBankBlockBehavior = Project.FindSubsystem<SubsystemMemoryBankBlockBehavior>(true);
                    SubsystemEditableItemBehavior<MemoryBankData> editableItemBehavior = Project.FindSubsystem<SubsystemEditableItemBehavior<MemoryBankData>>(true);
                    int value = m_subsystemTerrain.Terrain.GetCellValue(pos.X, pos.Y, pos.Z);
                    if (Terrain.ExtractContents(value) == 186)
                    {
                        MemoryBankData memoryBankData = memoryBankBlockBehavior.GetBlockData(pos);
                        if (memoryBankData == null)
                        {
                            memoryBankData = new MemoryBankData();
                            editableItemBehavior.SetBlockData(pos, memoryBankData);
                        }
                        memoryBankData.LoadString(text);
                        memoryBankData.SaveString();
                    }
                }
                //memorydata type:imagemul/imagefour f1:女装图.png f2:图片数据.txt
                else if (commandData.Type == "imagemul" || commandData.Type == "imagefour")
                {
                    string f1 = (string)commandData.GetValue("f1");
                    string f2 = (string)commandData.GetValue("f2");
                    Stream stream = GetCommandFileStream(f1, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    Image image = Image.Load(stream);
                    string data = string.Empty;
                    if (commandData.Type == "imagemul")
                    {
                        for (int h = 0; h < image.Height; h++)
                        {
                            for (int w = 0; w < image.Width; w++)
                            {
                                Color pixelColor = image.GetPixel(w, h);
                                byte red = pixelColor.R;
                                byte green = pixelColor.G;
                                byte blue = pixelColor.B;
                                if (pixelColor.A < 20)
                                {
                                    data += 0;
                                }
                                else
                                {
                                    if (pixelColor.R == 111 && pixelColor.G == 111 && pixelColor.B == 111)
                                    {
                                        data += 1;
                                        continue;
                                    }
                                    int sign = DataHandle.GetColorIndex(pixelColor, 1) + 7;
                                    data += DataHandle.NumberToSignal(sign);
                                }
                            }
                            data += "\n";
                        }
                    }
                    else
                    {
                        for (int h = 0; h < image.Height; h = h + 2)
                        {
                            for (int w = 0; w < image.Width; w = w + 2)
                            {
                                int[] slot = new int[4];
                                for (int t = 0; t < 4; t++)
                                {
                                    Color pixelColor = Color.Black;
                                    switch (t)
                                    {
                                        case 0: pixelColor = image.GetPixel(w, h); break;
                                        case 1: pixelColor = image.GetPixel(w + 1, h); break;
                                        case 2: pixelColor = image.GetPixel(w, h + 1); break;
                                        case 3: pixelColor = image.GetPixel(w + 1, h + 1); break;
                                        default: break;
                                    }
                                    if ((pixelColor.R == 111 && pixelColor.G == 111 && pixelColor.B == 111) || pixelColor.A < 20)
                                    {
                                        slot[t] = 0;
                                    }
                                    else
                                    {
                                        slot[t] = (DataHandle.GetColorIndex(pixelColor, 1) == 0) ? 0 : 1;
                                    }
                                }
                                int sign = slot[0] + slot[1] * 2 + slot[2] * 4 + slot[3] * 8;
                                data += DataHandle.NumberToSignal(sign);
                            }
                            data += "\n";
                        }
                    }
                    data += "###\n";
                    Stream stream2 = GetCommandFileStream(f2, OpenFileMode.CreateOrOpen);
                    stream2.Position = stream2.Length;
                    using (StreamWriter streamWriter = new StreamWriter(stream2))
                    {
                        streamWriter.WriteLine(data);
                        streamWriter.Flush();
                    }
                    stream.Dispose();
                    stream2.Dispose();
                }
                //memorydata type:rank f1:图片数据.txt f2:图像帧数据.txt
                else if (commandData.Type == "rank")
                {
                    string f1 = (string)commandData.GetValue("f1");
                    string f2 = (string)commandData.GetValue("f2");
                    Stream stream = GetCommandFileStream(f1, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    int n = 0;
                    int m = 0;
                    string line = string.Empty;
                    StreamReader streamreader = new StreamReader(stream);
                    while ((line = streamreader.ReadLine()) != null)
                    {
                        if (line == "" || line == " ") continue;
                        if (m == 0) m = line.Length;
                        if (line == "###") break;
                        n++;
                    }
                    string[] datas = new string[n * m];
                    int i = 0;
                    stream.Position = 0L;
                    StreamReader streamreader2 = new StreamReader(stream);
                    while ((line = streamreader2.ReadLine()) != null)
                    {
                        if (line == "" || line == " ") continue;
                        if (line == "###")
                        {
                            i = 0;
                            continue;
                        }
                        for (int j = 0; j < m; j++)
                        {
                            if (datas[i * m + j] == null) datas[i * m + j] = "";
                            datas[i * m + j] = datas[i * m + j] + line[j];
                        }
                        i++;
                    }
                    string writedata = string.Empty;
                    Stream stream2 = GetCommandFileStream(f2, OpenFileMode.CreateOrOpen);
                    StreamWriter streamwriter = new StreamWriter(stream2);
                    for (int l = 0; l < datas.Length; l++)
                    {
                        writedata = datas[l] + (((int)(l % m) == m - 1) ? "\n###" : "");
                        streamwriter.WriteLine(writedata);
                    }
                    streamwriter.Flush();
                    stream.Dispose();
                    stream2.Dispose();
                }
                //memorydata type:load+x-y/load-x-y/load+z-y/load-z-y/load+x+z/load-x-z pos:0,0,0 r:5 c:5 f:图像帧数据.txt
                else if (commandData.Type.StartsWith("load"))
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int r = (int)commandData.GetValue("r");
                    int c = (int)commandData.GetValue("c");
                    string f = (string)commandData.GetValue("f");
                    SubsystemMemoryBankBlockBehavior memoryBankBlockBehavior = Project.FindSubsystem<SubsystemMemoryBankBlockBehavior>(true);
                    SubsystemEditableItemBehavior<MemoryBankData> editableItemBehavior = Project.FindSubsystem<SubsystemEditableItemBehavior<MemoryBankData>>(true);
                    Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    StreamReader streamreader = new StreamReader(stream);
                    string line = string.Empty;
                    int fail = 0;
                    int x = pos.X;
                    int y = pos.Y;
                    int z = pos.Z;
                    while ((line = streamreader.ReadLine()) != null)
                    {
                        if (line == "" || line == " ") continue;
                        if (line.StartsWith("###"))
                        {
                            switch (commandData.Type)
                            {
                                case "load+x-y": x = pos.X; y -= r; break;
                                case "load-x-y": x = pos.X; y -= r; break;
                                case "load+z-y": z = pos.Z; y -= r; break;
                                case "load-z-y": z = pos.Z; y -= r; break;
                                case "load+x+z": x = pos.X; z += r; break;
                                case "load-x-z": x = pos.X; z -= r; break;
                            }
                            continue;
                        }
                        int value = m_subsystemTerrain.Terrain.GetCellValue(x, y, z);
                        if (Terrain.ExtractContents(value) == 186)
                        {
                            MemoryBankData memoryBankData = memoryBankBlockBehavior.GetBlockData(new Point3(x, y, z));
                            if (memoryBankData == null)
                            {
                                memoryBankData = new MemoryBankData();
                                editableItemBehavior.SetBlockData(new Point3(x, y, z), memoryBankData);
                            }
                            memoryBankData.LoadString(line);
                            memoryBankData.SaveString();
                        }
                        else
                        {
                            fail++;
                        }
                        switch (commandData.Type)
                        {
                            case "load+x-y": x += c; break;
                            case "load-x-y": x -= c; break;
                            case "load+z-y": z += c; break;
                            case "load-z-y": z -= c; break;
                            case "load+x+z": x += c; break;
                            case "load-x-z": x -= c; break;
                        }
                    }
                    if (fail == 0)
                    {
                        ShowSubmitTips("M板数据已全部写入");
                    }
                    else
                    {
                        ShowSubmitTips(fail + "个坐标位置不存在M板，请检查指令输入是否正确");
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("world", delegate (CommandData commandData)         //切换与删除世界
            {
                //world type:default f:世界/秘境
                if (commandData.Type == "default")
                {
                    string f = (string)commandData.GetValue("f");
                    WorldInfo worldInfo = null;
                    foreach (var wi in WorldsManager.m_worldInfos)
                    {
                        if (f == wi.WorldSettings.Name)
                        {
                            worldInfo = wi;
                            GameManager.SaveProject(true, true);
                            GameManager.DisposeProject();
                            ScreensManager.SwitchScreen("GameLoading", worldInfo, null);
                            return SubmitResult.Success;
                        }
                    }
                    string path = Storage.CombinePaths(DataHandle.GetCommandPath(), f);
                    if (!Storage.DirectoryExists(path))
                    {
                        ShowSubmitTips("找不到文件目录" + path);
                        return SubmitResult.Fail;
                    }
                    worldInfo = WorldsManager.GetWorldInfo(path);
                    GameManager.SaveProject(true, true);
                    GameManager.DisposeProject();
                    ScreensManager.SwitchScreen("GameLoading", worldInfo, null);
                }
                //world type:create f:世界/秘境
                else if (commandData.Type == "create")
                {
                    string f = (string)commandData.GetValue("f");
                    string path = Storage.CombinePaths(DataHandle.GetCommandPath(), f);
                    if (Storage.DirectoryExists(path))
                    {
                        ShowSubmitTips("Command目录已存在该世界");
                        return SubmitResult.Fail;
                    }
                    Storage.CreateDirectory(path);
                    WorldSettings worldSettings = GameManager.m_worldInfo.WorldSettings;
                    worldSettings.Seed = f.Replace("/", "$");
                    int num = 0;
                    int num2 = 1;
                    foreach (char c in worldSettings.Seed)
                    {
                        num += c * num2;
                        num2 += 29;
                    }
                    var valuesDictionary = new ValuesDictionary();
                    worldSettings.Save(valuesDictionary, liveModifiableParametersOnly: false);
                    valuesDictionary.SetValue("WorldDirectoryName", path);
                    valuesDictionary.SetValue("WorldSeed", num);
                    var valuesDictionary2 = new ValuesDictionary();
                    valuesDictionary2.SetValue("Players", new ValuesDictionary());
                    DatabaseObject databaseObject = DatabaseManager.GameDatabase.Database.FindDatabaseObject("GameProject", DatabaseManager.GameDatabase.ProjectTemplateType, throwIfNotFound: true);
                    var xElement = new XElement("Project");
                    XmlUtils.SetAttributeValue(xElement, "Guid", databaseObject.Guid);
                    XmlUtils.SetAttributeValue(xElement, "Name", "GameProject");
                    XmlUtils.SetAttributeValue(xElement, "Version", VersionsManager.SerializationVersion);
                    var xElement2 = new XElement("Subsystems");
                    xElement.Add(xElement2);
                    var xElement3 = new XElement("Values");
                    XmlUtils.SetAttributeValue(xElement3, "Name", "GameInfo");
                    valuesDictionary.Save(xElement3);
                    xElement2.Add(xElement3);
                    var xElement4 = new XElement("Values");
                    XmlUtils.SetAttributeValue(xElement4, "Name", "Players");
                    valuesDictionary2.Save(xElement4);
                    xElement2.Add(xElement4);
                    using (Stream stream = Storage.OpenFile(Storage.CombinePaths(path, "Project.xml"), OpenFileMode.Create))
                    {
                        XmlUtils.SaveXmlToStream(xElement, stream, null, throwOnError: true);
                    }
                    ShowSubmitTips("已在Command目录创建世界:" + f);
                }
                //world type:remove f:世界/秘境
                else if (commandData.Type == "remove")
                {
                    string f = (string)commandData.GetValue("f");
                    string path = Storage.CombinePaths(DataHandle.GetCommandPath(), f);
                    if (!Storage.DirectoryExists(path))
                    {
                        ShowSubmitTips("找不到文件目录" + path);
                        return SubmitResult.Fail;
                    }
                    WorldsManager.DeleteWorld(path);
                    ShowSubmitTips("已删除Command目录中的世界:" + f);
                }
                //world type:unzip f:秘境.scworld
                else if (commandData.Type == "unzip")
                {
                    string f = (string)commandData.GetValue("f");
                    string path = Storage.CombinePaths(GameManager.m_worldInfo.DirectoryName, f);
                    if (!Storage.FileExists(path))
                    {
                        ShowSubmitTips("当前存档中找不到子存档:" + f);
                        return SubmitResult.Fail;
                    }
                    Stream stream = Storage.OpenFile(path, OpenFileMode.CreateOrOpen);
                    string n = f.Replace(Storage.GetExtension(f), "");
                    string targetPath = Storage.CombinePaths(DataHandle.GetCommandPath(), n);
                    if (Storage.DirectoryExists(targetPath))
                    {
                        ShowSubmitTips("Command目录已经存在世界:" + n);
                        return SubmitResult.Fail;
                    }
                    Storage.CreateDirectory(targetPath);
                    WorldsManager.UnpackWorld(targetPath, stream, true);
                    stream.Dispose();
                    ShowSubmitTips("已成功在Command目录中创建世界:" + n);
                }
                //world type:delcurrent
                else if (commandData.Type == "delcurrent")
                {
                    string worldPath = GameManager.m_worldInfo.DirectoryName;
                    GameManager.SaveProject(true, true);
                    GameManager.DisposeProject();
                    WorldsManager.DeleteWorld(worldPath);
                    ScreensManager.SwitchScreen("MainMenu");
                }
                //world type:decipher f:秘境.txt
                else if (commandData.Type == "decipher")
                {
                    string f = (string)commandData.GetValue("f");
                    string path = Storage.CombinePaths(GameManager.m_worldInfo.DirectoryName, f);
                    if (!Storage.FileExists(path))
                    {
                        ShowSubmitTips("当前存档中找不到:" + f);
                        return SubmitResult.Fail;
                    }
                    CommandData commandData2 = new CommandData(commandData.Position, commandData.Line);
                    commandData2.Type = "unzip";
                    commandData2.Data["f"] = f;
                    Submit("world", commandData2, false);
                }
                return SubmitResult.Success;
            });
            AddFunction("texture", delegate (CommandData commandData)       //更换材质
            {
                //texture type:default
                if (commandData.Type == "default")
                {
                    Project.FindSubsystem<SubsystemBlocksTexture>().BlocksTexture = BlocksTexturesManager.DefaultBlocksTexture;
                    UpdateAllChunks(0f, TerrainChunkState.InvalidLight);
                }
                //texture type:block f:寂静岭.png
                else if (commandData.Type == "block")
                {
                    string f = (string)commandData.GetValue("f");
                    Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    if (!Png.IsPngStream(stream))
                    {
                        ShowSubmitTips("建议将图片转换为png格式，以免颜色错乱");
                    }
                    Texture2D texture = Texture2D.Load(stream);
                    if (!MathUtils.IsPowerOf2(texture.Width) || !MathUtils.IsPowerOf2(texture.Height))
                    {
                        ShowSubmitTips("材质图长和宽需为2的指数倍");
                        return SubmitResult.Fail;
                    }
                    Project.FindSubsystem<SubsystemBlocksTexture>().BlocksTexture = texture;
                    UpdateAllChunks(0f, TerrainChunkState.InvalidLight);
                    stream.Dispose();
                }
                //texture type:cmdcreature obj:tiger f:黑虎材质.png
                else if (commandData.Type == "cmdcreature")
                {
                    string obj = (string)commandData.GetValue("obj");
                    string f = (string)commandData.GetValue("f");
                    Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    if (!Png.IsPngStream(stream))
                    {
                        ShowSubmitTips("建议将图片转换为png格式，以免颜色错乱");
                    }
                    Texture2D texture = Texture2D.Load(stream);
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        ComponentModel componentModel = body.Entity.FindComponent<ComponentModel>();
                        if (componentModel != null)
                        {
                            componentModel.TextureOverride = texture;
                        }
                        return false;
                    });
                    stream.Dispose();
                    CreatureTextures[obj] = "$" + f;
                }
                //texture type:pakcreature obj:tiger opt:Tiger_White
                else if (commandData.Type == "pakcreature")
                {
                    string obj = (string)commandData.GetValue("obj");
                    string opt = (string)commandData.GetValue("opt");
                    string path = Storage.CombinePaths("Textures/Creatures", opt);
                    Texture2D texture = null;
                    try
                    {
                        texture = ContentManager.Get<Texture2D>(path);
                    }
                    catch
                    {
                        ShowSubmitTips("Content资源包不存在文件:" + path);
                        return SubmitResult.Fail;
                    }
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        ComponentModel componentModel = body.Entity.FindComponent<ComponentModel>();
                        if (componentModel != null)
                        {
                            componentModel.TextureOverride = texture;
                        }
                        return false;
                    });
                    CreatureTextures[obj] = path;
                }
                //texture type:resetcreature obj:tiger
                else if (commandData.Type == "resetcreature")
                {
                    string obj = (string)commandData.GetValue("obj");
                    Texture2D texture = null;
                    try
                    {
                        texture = ContentManager.Get<Texture2D>(EntityInfoManager.GetEntityInfo(obj).Texture);
                    }
                    catch
                    {
                        ShowSubmitTips(obj + "材质恢复失败，发生未知错误");
                        return SubmitResult.Fail;
                    }
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        ComponentModel componentModel = body.Entity.FindComponent<ComponentModel>();
                        if (componentModel != null)
                        {
                            componentModel.TextureOverride = texture;
                        }
                        return false;
                    });
                    if (CreatureTextures.ContainsKey(obj))
                    {
                        CreatureTextures.Remove(obj);
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("model", delegate (CommandData commandData)         //更换生物模型
            {
                //model type:default obj:boat con:false f:exmodel.dae
                if (commandData.Type == "default")
                {
                    string obj = (string)commandData.GetValue("obj");
                    bool con = (bool)commandData.GetValue("con");
                    string f = (string)commandData.GetValue("f");
                    Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    Model model = Model.Load(stream, true);
                    stream.Dispose();
                    string modelType = EntityInfoManager.GetModelType(model);
                    string modelType2 = EntityInfoManager.GetModelType(obj);
                    if (modelType != modelType2 && !con && obj != "boat")
                    {
                        string n = EntityInfoManager.GetModelTypeDisplayName(modelType);
                        string n2 = EntityInfoManager.GetModelTypeDisplayName(modelType2);
                        ShowSubmitTips(string.Format("导入模型为{0},当前生物为{1},\n模型不匹配,请选择其他生物对象", n, n2));
                        return SubmitResult.Fail;
                    }
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        ComponentModel componentModel = body.Entity.FindComponent<ComponentModel>();
                        if (componentModel != null)
                        {
                            try
                            {
                                componentModel.Model = model;
                            }
                            catch
                            {
                            }
                        }
                        return false;
                    });
                    CreatureModels[obj] = "$" + f;
                }
                //model type:pakmodel obj:tiger con:false opt:Horse
                else if (commandData.Type == "pakmodel")
                {
                    string obj = (string)commandData.GetValue("obj");
                    bool con = (bool)commandData.GetValue("con");
                    string opt = (string)commandData.GetValue("opt");
                    string path = Storage.CombinePaths("Models", opt);
                    Model model = ContentManager.Get<Model>(path);
                    string modelType = EntityInfoManager.GetModelType(model);
                    string modelType2 = EntityInfoManager.GetModelType(obj);
                    if (modelType != modelType2 && !con && obj != "boat")
                    {
                        string n = EntityInfoManager.GetModelTypeDisplayName(modelType);
                        string n2 = EntityInfoManager.GetModelTypeDisplayName(modelType2);
                        ShowSubmitTips(string.Format("导入模型为{0},当前生物为{1},\n模型不匹配,请选择其他生物对象", n, n2));
                        return SubmitResult.Fail;
                    }
                    ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        ComponentModel componentModel = body.Entity.FindComponent<ComponentModel>();
                        if (componentModel != null)
                        {
                            try
                            {
                                componentModel.Model = model;
                            }
                            catch
                            {
                            }
                        }
                        return false;
                    });
                    CreatureModels[obj] = path;
                }
                //model type:resetall
                else if (commandData.Type == "resetall")
                {
                    CreatureModels.Clear();
                    ErgodicBody("all", delegate (ComponentBody body)
                    {
                        string name = body.Entity.ValuesDictionary.DatabaseObject.Name.ToLower();
                        EntityInfo entityInfo = EntityInfoManager.GetEntityInfo(name);
                        if (entityInfo != null)
                        {
                            ComponentModel componentModel = body.Entity.FindComponent<ComponentModel>();
                            if (componentModel != null)
                            {
                                componentModel.Model = ContentManager.Get<Model>(entityInfo.Model);
                            }
                        }
                        return false;
                    });
                }
                return SubmitResult.Success;
            });
            AddFunction("image", delegate (CommandData commandData)         //生成像素画
            {
                WithdrawBlockManager wbManager = null;
                if (WithdrawBlockManager.WithdrawMode) wbManager = new WithdrawBlockManager();
                //image type:default/tile/rotate pos:0,0,0 con:false f:女装图.png 
                Point3 pos = GetOnePoint("pos", commandData);
                bool con = (bool)commandData.GetValue("con");
                string f = (string)commandData.GetValue("f");
                Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                if (stream == null) return SubmitResult.Fail;
                if (!Png.IsPngStream(stream))
                {
                    ShowSubmitTips("建议将图片转换为png格式，以免颜色错乱");
                }
                Image image = Image.Load(stream);
                stream.Dispose();
                bool isDefault = (commandData.Type == "default");
                bool isTile = (commandData.Type == "tile");
                bool isRotate = (commandData.Type == "rotate");
                for (int h = 0; h < image.Height; h++)
                {
                    for (int w = 0; w < image.Width; w++)
                    {
                        Color pixelColor = image.GetPixel(w, h);
                        Point3 p = Point3.Zero;
                        int value = 0;
                        if (isDefault) p = new Point3(pos.X - w, pos.Y - h, pos.Z);
                        else if (isTile) p = new Point3(pos.X - w, pos.Y, pos.Z - h);
                        else if (isRotate) p = new Point3(pos.X, pos.Y - h, pos.Z - w);
                        if (p.Y > 0 && p.Y < 255)
                        {
                            if (pixelColor.A >= 20)
                            {
                                if (con)
                                {
                                    value = Command.ClayBlock.SetCommandColor(72, pixelColor);
                                }
                                else
                                {
                                    if (!ColorIndexCaches.TryGetValue(pixelColor, out value))
                                    {
                                        value = DataHandle.GetColorIndex(pixelColor) * 32768 + 16456;
                                        if (ColorIndexCaches.Count < 1000)
                                        {
                                            ColorIndexCaches[pixelColor] = value;
                                        }
                                    }
                                }
                            }
                            ChangeBlockValue(wbManager, p.X, p.Y, p.Z, value);
                        }
                    }
                }
                Point3 minPoint = pos;
                if (isDefault) minPoint = pos - new Point3(image.Width, image.Height, 0);
                else if (isTile) minPoint = pos - new Point3(image.Width, 0, image.Height);
                else if (isRotate) minPoint = pos - new Point3(0, image.Height, image.Width);
                PlaceReprocess(wbManager, commandData, true, minPoint, pos);
                return SubmitResult.Success;
            });
            AddFunction("pattern", delegate (CommandData commandData)       //生成光点贴图
            {
                //pattern type:default pos:0,0,0 color:255,255,255 vec3:0,0,0 v:10 f:melon.png opt:default
                //pattern type:online pos:0,0,0 color:255,255,255 vec3:0,0,0 v:10 web:melon.png opt:default
                if (commandData.Type == "default" || commandData.Type == "online")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    Color color = (Color)commandData.GetValue("color");
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    int v = (int)commandData.GetValue("v");
                    string opt = (string)commandData.GetValue("opt");
                    bool online = (commandData.Type != "default");
                    bool con = !online ? false : (bool)commandData.GetValue("con");
                    string f = online ? string.Empty : (string)commandData.GetValue("f");
                    string fix = !online ? string.Empty : (string)commandData.GetValue("fix");
                    bool isTile = (opt == "tile");
                    bool isRotate = (opt == "rotate");
                    Vector3 offset = vec3 / 10f;
                    Pattern pattern = new Pattern();
                    pattern.Point = pos;
                    pattern.Color = color;
                    pattern.Size = v / 20.418f;
                    pattern.TexName = f;
                    pattern.Position = offset + new Vector3(pos) + new Vector3(0.5f, 0.5f, 0f);
                    pattern.Up = new Vector3(0f, -1f, 0f);
                    pattern.Right = new Vector3(-1f, 0f, 0f);
                    if (v <= 0 && PatternPoints.ContainsKey(pos))
                    {
                        PatternPoints.Remove(pos);
                    }
                    if (isTile)
                    {
                        pattern.Up = new Vector3(0f, 0f, -1f);
                        pattern.Position = offset + new Vector3(pos) + new Vector3(0.5f, 1f, 0.5f);
                    }
                    else if (isRotate)
                    {
                        pattern.Right = new Vector3(0f, 0f, -1f);
                        pattern.Position = offset + new Vector3(pos) + new Vector3(1f, 0.5f, 0.5f);
                    }
                    if (!online)
                    {
                        Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                        if (stream == null) return SubmitResult.Fail;
                        if (!Png.IsPngStream(stream))
                        {
                            ShowSubmitTips("建议将图片转换为png格式，以免颜色错乱");
                        }
                        Texture2D texture = Texture2D.Load(stream);
                        pattern.LWratio = (float)texture.Height / (float)texture.Width;
                        pattern.Texture = texture;
                        PatternPoints[pos] = pattern;
                        stream.Dispose();
                    }
                    else
                    {
                        ShowSubmitTips("图片正在生成,请保证网络良好");
                        Task.Run(delegate
                        {
                            CancellableProgress progress = new CancellableProgress();
                            WebManager.Get(fix, null, null, progress, delegate (byte[] result)
                            {
                                Stream stream = new MemoryStream(result);
                                if (stream != null)
                                {
                                    StreamReader streamReader = new StreamReader(stream);
                                    string pic = GetPictureURL(streamReader.ReadToEnd());
                                    if (!string.IsNullOrEmpty(pic))
                                    {
                                        WebManager.Get(pic, null, null, progress, delegate (byte[] result2)
                                        {
                                            Stream stream2 = new MemoryStream(result2);
                                            if (stream2 != null)
                                            {
                                                if (con)
                                                {
                                                    string commandPath = Storage.GetSystemPath(DataHandle.GetCommandPath());
                                                    pattern.TexName = pic.Substring(pic.LastIndexOf('/') + 1);
                                                    FileStream fileStream = new FileStream(Storage.CombinePaths(commandPath, pattern.TexName), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                                                    fileStream.Write(result2, 0, result2.Length);
                                                    fileStream.Flush();
                                                    fileStream.Dispose();
                                                }
                                                Texture2D texture = Texture2D.Load(stream2);
                                                pattern.LWratio = (float)texture.Height / (float)texture.Width;
                                                pattern.Texture = texture;
                                                PatternPoints[pos] = pattern;
                                                stream2.Dispose();
                                                ShowSubmitTips("图片生成成功");
                                            }
                                            else
                                            {
                                                ShowSubmitTips("图片生成失败");
                                            }
                                        }, delegate (Exception error)
                                        {
                                            ShowSubmitTips("图片生成失败");
                                        });
                                    }
                                    else
                                    {
                                        ShowSubmitTips("图片URL获取失败");
                                    }
                                }
                            }, delegate (Exception error)
                            {
                                ShowSubmitTips("接口连接失败");
                            });
                        });
                    }
                }
                //pattern type:font text:test pos:0,0,0 color:255,255,255 vec3:0,0,0 v:10 t:1
                else if (commandData.Type == "font")
                {
                    string text = (string)commandData.GetValue("text");
                    Point3 pos = GetOnePoint("pos", commandData);
                    Color color = (Color)commandData.GetValue("color");
                    Vector3 vec3 = (Vector3)commandData.GetValue("vec3");
                    int v = (int)commandData.GetValue("v");
                    string opt = (string)commandData.GetValue("opt");
                    PatternFont pt = new PatternFont();
                    pt.Point = pos;
                    pt.Position = new Vector3(pos) + vec3 / 100f;
                    pt.Text = text;
                    pt.Size = (float)v / 1000f;
                    pt.Color = color;
                    switch (opt)
                    {
                        case "+x-y": pt.Right = new Vector3(1f, 0, 0); pt.Down = new Vector3(0, -1f, 0); pt.Position += new Vector3(0, 1f, 0); break;
                        case "-x-y": pt.Right = new Vector3(-1f, 0, 0); pt.Down = new Vector3(0, -1f, 0); pt.Position += new Vector3(1f, 1f, 0); break;
                        case "+z-y": pt.Right = new Vector3(0, 0, 1f); pt.Down = new Vector3(0, -1f, 0); pt.Position += new Vector3(0, 1f, 0); break;
                        case "-z-y": pt.Right = new Vector3(0, 0, -1f); pt.Down = new Vector3(0, -1f, 0); pt.Position += new Vector3(0, 1f, 1f); break;
                        case "+x+z": pt.Right = new Vector3(1f, 0, 0); pt.Down = new Vector3(0, 0, 1f); break;
                        case "-x+z": pt.Right = new Vector3(-1f, 0, 0); pt.Down = new Vector3(0, 0, 1f); pt.Position += new Vector3(1f, 0, 0); break;
                        default: pt.Right = new Vector3(1f, 0, 0); pt.Down = new Vector3(0, -1f, 0); pt.Position += new Vector3(0, 1f, 0); break;
                    }
                    PatternFonts[pos] = pt;
                }
                //pattern type:remove pos1:0,0,0 pos2:1,1,1
                else if (commandData.Type == "remove")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    List<Point3> toRemove = new List<Point3>();
                    List<Point3> toRemove2 = new List<Point3>();
                    bool isSuccess = false;
                    foreach (Point3 point in PatternPoints.Keys)
                    {
                        if (cube.Exist(PatternPoints[point].Position))
                        {
                            toRemove.Add(point);
                            isSuccess = true;
                        }
                    }
                    foreach (Point3 remove in toRemove)
                    {
                        PatternPoints.Remove(remove);
                    }
                    foreach (Point3 point in PatternFonts.Keys)
                    {
                        if (cube.Exist(PatternFonts[point].Position))
                        {
                            toRemove2.Add(point);
                            isSuccess = true;
                        }
                    }
                    foreach (Point3 remove in toRemove2)
                    {
                        PatternFonts.Remove(remove);
                    }
                    if (!isSuccess)
                    {
                        ShowSubmitTips("指定区域不存在光点贴图");
                    }
                }
                //pattern type:removeall
                else if (commandData.Type == "removeall")
                {
                    PatternPoints.Clear();
                    PatternFonts.Clear();
                }
                //pattern type:screenadd vec2:0,0 size:100,100 con:true v:0 con:false text:吃瓜 f:melon.png
                else if (commandData.Type == "screenadd")
                {
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    int v = (int)commandData.GetValue("v");
                    string size = (string)commandData.GetValue("size");
                    bool con1 = (bool)commandData.GetValue("con1");
                    bool con2 = (bool)commandData.GetValue("con2");
                    string text = (string)commandData.GetValue("text");
                    string f = (string)commandData.GetValue("f");
                    Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    if (!Png.IsPngStream(stream))
                    {
                        ShowSubmitTips("建议将图片转换为png格式，以免颜色错乱");
                    }
                    Texture2D texture = Texture2D.Load(stream);
                    stream.Close();
                    if (ScreenPatterns.ContainsKey(text))
                    {
                        ScreenPatterns.Remove(text);
                    }
                    m_screenPatternsWidget.IsVisible = true;
                    Vector2 patternSize = DataHandle.GetVector2Value(size);
                    if (con1)
                    {
                        patternSize = new Vector2(patternSize.X, patternSize.X * texture.Height / texture.Width);
                    }
                    int mx = (int)(m_componentPlayer.GameWidget.ActualSize.X / 2) - (int)(patternSize.X / 2);
                    int my = (int)(m_componentPlayer.GameWidget.ActualSize.Y / 2) - (int)(patternSize.Y / 2);
                    if (con2)
                    {
                        BitmapButtonWidget buttonWidget = new BitmapButtonWidget();
                        buttonWidget.NormalSubtexture = new Subtexture(texture, Vector2.Zero, Vector2.One);
                        buttonWidget.ClickedSubtexture = new Subtexture(texture, Vector2.Zero, Vector2.One);
                        buttonWidget.Color = Color.White;
                        buttonWidget.Size = patternSize;
                        buttonWidget.Margin = new Vector2(mx, my) + vec2;
                        ScreenPattern screenPattern = new ScreenPattern();
                        screenPattern.Name = text;
                        screenPattern.Texture = f;
                        screenPattern.Layer = v;
                        screenPattern.OutTime = 0;
                        screenPattern.Widget = buttonWidget;
                        ScreenPatterns.Add(text, screenPattern);
                    }
                    else
                    {
                        RectangleWidget rectangleWidget = new RectangleWidget();
                        rectangleWidget.Subtexture = new Subtexture(texture, Vector2.Zero, Vector2.One);
                        rectangleWidget.FillColor = Color.White;
                        rectangleWidget.OutlineColor = new Color(0, 0, 0, 0);
                        rectangleWidget.Size = patternSize;
                        rectangleWidget.Margin = new Vector2(mx, my) + vec2;
                        ScreenPattern screenPattern = new ScreenPattern();
                        screenPattern.Name = text;
                        screenPattern.Texture = f;
                        screenPattern.Layer = v;
                        screenPattern.OutTime = 0;
                        screenPattern.Widget = rectangleWidget;
                        ScreenPatterns.Add(text, screenPattern);
                    }
                    if (m_screenPatternsWidget.Children.Count > 0)
                    {
                        m_screenPatternsWidget.Children.Clear();
                    }
                    ScreenPattern[] arsp = ScreenPatterns.Values.ToArray();
                    for (int i = 0; i < arsp.Length - 1; i++)
                    {
                        for (int j = 0; j < arsp.Length - 1 - i; j++)
                        {
                            if (arsp[j].Layer > arsp[j + 1].Layer)
                            {
                                var temp = arsp[j + 1];
                                arsp[j + 1] = arsp[j];
                                arsp[j] = temp;
                            }
                        }
                    }
                    foreach (var sp in arsp)
                    {
                        m_screenPatternsWidget.Children.Add(sp.Widget);
                    }
                }
                //pattern type:screenremove text:melon
                else if (commandData.Type == "screenremove")
                {
                    string text = (string)commandData.GetValue("text");
                    if (ScreenPatterns.TryGetValue(text, out ScreenPattern value))
                    {
                        m_screenPatternsWidget.IsVisible = true;
                        m_screenPatternsWidget.Children.Remove(value.Widget);
                        ScreenPatterns.Remove(text);
                    }
                    else
                    {
                        ShowSubmitTips(string.Format("屏幕中没有标识名为{0}的贴图", text));
                    }
                }
                //pattern type:screenclear
                else if (commandData.Type == "screenclear")
                {
                    m_screenPatternsWidget.Children.Clear();
                    ScreenPatterns.Clear();
                }
                return SubmitResult.Success;
            });
            AddFunction("music", delegate (CommandData commandData)         //播放音乐
            {
                //music type:default f:再回首.wav
                if (commandData.Type == "default")
                {
                    string f = (string)commandData.GetValue("f");
                    string ex = Storage.GetExtension(f).ToLower();
                    if (m_commandMusic.Sound == null || (m_commandMusic.Sound != null && m_commandMusic.Name != f))
                    {
                        Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                        if (stream == null) return SubmitResult.Fail;
                        SoundBuffer soundbuffer = SoundBuffer.Load(stream);
                        m_commandMusic = new CommandMusic(f, new Sound(soundbuffer));
                        m_commandMusic.Sound.Play();
                        ShowSubmitTips("开始播放歌曲：" + m_commandMusic.Name);
                        stream.Dispose();
                    }
                    else if (m_commandMusic.Sound != null && m_commandMusic.Name == f)
                    {
                        if (m_commandMusic.Sound.State == SoundState.Paused)
                        {
                            ShowSubmitTips("继续播放歌曲：" + m_commandMusic.Name);
                        }
                        else if (m_commandMusic.Sound.State == SoundState.Stopped)
                        {
                            ShowSubmitTips("开始播放歌曲：" + m_commandMusic.Name);
                        }
                        m_commandMusic.Sound.Play();
                    }
                }
                //music type:pause/stop/reset
                else if (commandData.Type == "pause" || commandData.Type == "stop" || commandData.Type == "reset")
                {
                    if (m_commandMusic.Sound == null)
                    {
                        ShowSubmitTips("当前后台无歌曲，请先播放歌曲");
                        return SubmitResult.Fail;
                    }
                    switch (commandData.Type)
                    {
                        case "pause":
                            {
                                if (m_commandMusic.Sound.State == SoundState.Playing)
                                {
                                    m_commandMusic.Sound.Pause();
                                    ShowSubmitTips("已暂停后台歌曲:" + m_commandMusic.Name);
                                }
                                break;
                            }
                        case "stop":
                            {
                                m_commandMusic.Sound.Stop();
                                ShowSubmitTips("已停止后台歌曲:" + m_commandMusic.Name);
                                break;
                            }
                        case "reset":
                            {
                                m_commandMusic.Sound.Stop();
                                m_commandMusic.Sound.Play();
                                ShowSubmitTips("重新播放歌曲:" + m_commandMusic.Name);
                                break;
                            }
                        default: break;
                    }
                }
                //music type:volume v:10
                else if (commandData.Type == "volume")
                {
                    int v = (int)commandData.GetValue("v");
                    if (m_commandMusic.Sound == null)
                    {
                        ShowSubmitTips("当前后台无歌曲，请先播放歌曲");
                        return SubmitResult.Fail;
                    }
                    m_commandMusic.Sound.Volume = v / 10f;
                }
                return SubmitResult.Success;
            });
            AddFunction("audio", delegate (CommandData commandData)         //播放音效
            {
                //audio type:default f:鸭叫.wav v:10 p:10
                if (commandData.Type == "default")
                {
                    string f = (string)commandData.GetValue("f");
                    int v = (int)commandData.GetValue("v");
                    int p = (int)commandData.GetValue("p");
                    string ex = Storage.GetExtension(f).ToLower();
                    if (ex != ".wav")
                    {
                        ShowSubmitTips("目前仅支持wav格式的音频");
                        return SubmitResult.Fail;
                    }
                    if (p != 15 && v != 0)
                    {
                        Vector3 position = new Vector3(commandData.Position);
                        float pitch = CommandMusic.GetPitch(p);
                        float volume = v / 15f;
                        Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                        if (stream == null) return SubmitResult.Fail;
                        SoundBuffer soundbuffer = SoundBuffer.Load(stream);
                        float k = m_subsystemAudio.CalculateVolume(m_subsystemAudio.CalculateListenerDistance(position), 0.5f + 5f * volume);
                        (new Sound(soundbuffer, volume * k, pitch, 0f, isLooped: false, disposeOnStop: true)).Play();
                        stream.Dispose();
                    }
                }
                //audio type:contentpak opt:Rain v:10 p:10
                else if (commandData.Type == "contentpak")
                {
                    string opt = (string)commandData.GetValue("opt");
                    int v = (int)commandData.GetValue("v");
                    int p = (int)commandData.GetValue("p");
                    if (p != 15 && v != 0)
                    {
                        Vector3 position = new Vector3(commandData.Position);
                        float pitch = CommandMusic.GetPitch(p);
                        float volume = v / 15f;
                        m_subsystemAudio.PlaySound("Audio/" + opt, volume, pitch, position, 0.5f + 5f * volume, autoDelay: true);
                    }
                }
                //audio type:piano p:10 o:4 v:15
                else if (commandData.Type == "piano")
                {
                    int p = (int)commandData.GetValue("p");
                    int o = (int)commandData.GetValue("o");
                    int v = (int)commandData.GetValue("v");
                    if (p != 15 && v != 0)
                    {
                        Vector3 position = new Vector3(commandData.Position) + new Vector3(0.5f);
                        float volume = v / 15f;
                        float pitch = CommandMusic.GetRealPitch(p, ref o);
                        if (o > 7)
                        {
                            o = 7;
                            pitch = 1f;
                        }
                        float minDistance = 0.5f + v / 3f;
                        m_subsystemAudio.PlaySound($"CommandPiano/PianoC{o}", volume, pitch, position, minDistance, autoDelay: true);
                        //float loudness = (v < 8) ? 0.25f : 0.5f;
                        //float range = MathUtils.Lerp(2f, 20f, v / 15f);
                        //Project.FindSubsystem<SubsystemNoise>().MakeNoise(position, loudness, range);
                        SoundParticleSystem particleSystem = new SoundParticleSystem(m_subsystemTerrain, position + new Vector3(0, 0.5f, 0), new Vector3(0, 1, 0));
                        if (particleSystem.SubsystemParticles == null)
                        {
                            m_subsystemParticles.AddParticleSystem(particleSystem);
                        }
                        Vector3 hsv = new Vector3(22.5f * p + (new Random()).Float(0f, 22f), 0.5f + v / 30f, 1f);
                        particleSystem.AddNote(new Color(Color.HsvToRgb(hsv)));
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("build", delegate (CommandData commandData)         //生成建筑
            {
                WithdrawBlockManager wbManager = null;
                if (WithdrawBlockManager.WithdrawMode) wbManager = new WithdrawBlockManager();
                //build type:default pos:0,0,0 f:小丑房.txt
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    string f = (string)commandData.GetValue("f");
                    string opt = (string)commandData.GetValue("opt");
                    Task.Run(delegate
                    {
                        Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                        StreamReader streamReader = new StreamReader(stream);
                        int i = 1;
                        string line = string.Empty;
                        Point3 maxPoint = Point3.Zero;
                        int value = 0;
                        try
                        {
                            while ((line = streamReader.ReadLine()) != null)
                            {
                                string[] words = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                if (words.Length == 4 || words.Length == 6)
                                {
                                    try
                                    {
                                        Point3 p = Point3.Zero;
                                        switch (opt)
                                        {
                                            case "x-y-z": p = new Point3(int.Parse(words[0]), int.Parse(words[1]), int.Parse(words[2])); break;
                                            case "x-z-y": p = new Point3(int.Parse(words[0]), int.Parse(words[2]), int.Parse(words[1])); break;
                                            case "y-x-z": p = new Point3(int.Parse(words[1]), int.Parse(words[0]), int.Parse(words[2])); break;
                                            case "y-z-x": p = new Point3(int.Parse(words[1]), int.Parse(words[2]), int.Parse(words[0])); break;
                                            case "z-x-y": p = new Point3(int.Parse(words[2]), int.Parse(words[0]), int.Parse(words[1])); break;
                                            case "z-y-x": p = new Point3(int.Parse(words[2]), int.Parse(words[1]), int.Parse(words[0])); break;
                                        }
                                        p = p + pos;
                                        if (p.X > maxPoint.X) maxPoint.X = p.X;
                                        if (p.Y > maxPoint.Y) maxPoint.Y = p.Y;
                                        if (p.Z > maxPoint.Z) maxPoint.Z = p.Z;
                                        if (words.Length == 4)
                                        {
                                            value = int.Parse(words[3]);
                                        }
                                        else
                                        {
                                            value = Command.ClayBlock.SetCommandColor(72, new Color(int.Parse(words[3]), int.Parse(words[4]), int.Parse(words[5])));
                                        }
                                        ChangeBlockValue(wbManager, p.X, p.Y, p.Z, value);
                                    }
                                    catch
                                    {
                                        ShowSubmitTips(string.Format("方块生成发生错误，错误发生在第{0}行", i));
                                    }
                                }
                                i++;
                            }
                        }
                        catch
                        {
                        }
                        PlaceReprocess(wbManager, commandData, true, pos, maxPoint);
                        stream.Dispose();
                    });
                }
                //build type:copycache pos:0,0,0
                else if (commandData.Type == "copycache")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    if (CopyBlockManager == null)
                    {
                        ShowSubmitTips("缓存区不存在复制的建筑，\n请先复制区域，复制指令为copyblock$copycache");
                        return SubmitResult.Fail;
                    }
                    CopyBlockManager.SubsystemCommandDef = this;
                    CopyBlockManager.WBManager = wbManager;
                    CopyBlockManager.CopyFromCache(pos);
                    PlaceReprocess(wbManager, commandData, true, pos, pos + CopyBlockManager.CubeArea.MaxPoint - CopyBlockManager.CubeArea.MinPoint);
                    ShowSubmitTips("已全部生成！\n如果复制工作已完成，可以重启游戏以清除后台方块缓存");
                }
                return SubmitResult.Success;
            });
            AddFunction("copyfile", delegate (CommandData commandData)      //复制资源文件
            {
                //copyfile type:default fix:melon.png
                if (commandData.Type == "default")
                {
                    string fix = (string)commandData.GetValue("fix");
                    string path = Storage.CombinePaths(DataHandle.GetCommandPath(), fix);
                    if (!Storage.FileExists(path))
                    {
                        ShowSubmitTips("Command目录不存在文件:" + fix);
                        return SubmitResult.Fail;
                    }
                    string oldfile = Storage.GetSystemPath(path);
                    string newfile = Storage.CombinePaths(Storage.GetSystemPath(GameManager.m_worldInfo.DirectoryName), fix);
                    FileStream fs1 = new FileStream(oldfile, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    FileStream fs2 = new FileStream(newfile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                    fs1.CopyTo(fs2);
                    fs1.Dispose();
                    fs2.Dispose();
                    ShowSubmitTips("已将指定文件复制到存档工作目录");
                }
                //copyfile type:folder fix:Command
                else if (commandData.Type == "folder")
                {
                    string fix = (string)commandData.GetValue("fix");
                    string path = Storage.CombinePaths(Storage.GetDirectoryName(DataHandle.GetCommandPath()), fix);
                    if (!Storage.DirectoryExists(path))
                    {
                        ShowSubmitTips("Command目录不存在文件夹:" + fix);
                        return SubmitResult.Fail;
                    }
                    string systemPath = Storage.GetSystemPath(path);
                    string worldPath = Storage.GetSystemPath(GameManager.m_worldInfo.DirectoryName);
                    foreach (string fname in Storage.ListFileNames(path))
                    {
                        string oldfile = Storage.CombinePaths(systemPath, fname);
                        string newfile = Storage.CombinePaths(worldPath, fname);
                        FileStream fs1 = new FileStream(oldfile, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                        FileStream fs2 = new FileStream(newfile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                        fs1.CopyTo(fs2);
                        fs1.Dispose();
                        fs2.Dispose();
                    }
                    ShowSubmitTips("已将指定文件夹所有文件复制到存档工作目录");
                }
                return SubmitResult.Success;
            });
            AddFunction("capture", delegate (CommandData commandData)       //游戏截图
            {
                //capture type:default
                ScreenCaptureManager.CapturePhoto(delegate
                {
                    ShowSubmitTips("图片已储存到图库");
                }, delegate
                {
                    ShowSubmitTips("图片截取失败，发生未知错误");
                });
                return SubmitResult.Success;
            });
            AddFunction("website", delegate (CommandData commandData)       //打开网站
            {
                //website type:default text:https[c]//m.schub.top/com
                string text = (string)commandData.GetValue("text");
                WebBrowserManager.LaunchBrowser(text);
                return SubmitResult.Success;
            });
            AddFunction("note", delegate (CommandData commandData)          //编辑查看笔记
            {
                //note type:default
                if (commandData.Type == "default")
                {
                    m_componentPlayer.ComponentGui.ModalPanelWidget = new NotesWidget(m_componentPlayer, Notes);
                }
                //note type:onlyread text:title size:100,100 vec2:0,0 color1:255,255,255 v1:10 color2:255,255,255 color3:255,255,255 v2:10
                else if (commandData.Type == "onlyread")
                {
                    string text = (string)commandData.GetValue("text");
                    string size = (string)commandData.GetValue("size");
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    int v1 = (int)commandData.GetValue("v1");
                    Color color1 = (Color)commandData.GetValue("color1");
                    int v2 = (int)commandData.GetValue("v2");
                    Color color2 = (Color)commandData.GetValue("color2");
                    Color color3 = (Color)commandData.GetValue("color3");
                    int v3 = (int)commandData.GetValue("v3");
                    if (Notes.TryGetValue(text, out string value))
                    {
                        m_screenLabelCanvasWidget.IsVisible = true;
                        m_screenLabelCloseTime = v1;
                        Vector2 canvasSize = DataHandle.GetVector2Value(size);
                        CanvasWidget canvasWidget = (CanvasWidget)m_screenLabelCanvasWidget;
                        canvasWidget.Size = canvasSize;
                        int mx = (int)(m_componentPlayer.GameWidget.ActualSize.X / 2) - (int)(canvasSize.X / 2);
                        int my = (int)(m_componentPlayer.GameWidget.ActualSize.Y / 2) - (int)(canvasSize.Y / 2);
                        m_componentPlayer.GameWidget.SetWidgetPosition(m_screenLabelCanvasWidget, new Vector2(mx, my) + vec2);
                        LabelWidget labelWidget = m_screenLabelCanvasWidget.Children.Find<LabelWidget>("Content");
                        labelWidget.Text = value.Replace("[n]", "\n").Replace("\t", "");
                        labelWidget.Color = color1;
                        labelWidget.FontScale = v2 / 50f;
                        RectangleWidget rectangleWidget = m_screenLabelCanvasWidget.Children.Find<RectangleWidget>("ScreenLabelRectangle");
                        rectangleWidget.FillColor = color2;
                        rectangleWidget.OutlineColor = color3;
                        rectangleWidget.OutlineThickness = v3 / 10f;
                    }
                    else
                    {
                        ShowSubmitTips(string.Format("没有标题名为{0}的笔记", text));
                    }
                }
                //note type:close
                else if (commandData.Type == "close")
                {
                    m_screenLabelCanvasWidget.IsVisible = false;
                }
                return SubmitResult.Success;
            });
            AddFunction("colorblock", delegate (CommandData commandData)    //彩色方块
            {
                //colorblock type:default id:72 color:255,255,255 con:false
                if (commandData.Type == "default")
                {
                    int id = (int)commandData.GetValue("id");
                    Color color = (Color)commandData.GetValue("color");
                    bool con = (bool)commandData.GetValue("con");
                    id = Terrain.ExtractContents(id);
                    int value = 0;
                    if (id == 72 || id == 12 || id == 13 || id == 14 || id == 225 || id == 256 || id == 15)
                    {
                        switch (id)
                        {
                            case 72: value = Command.ClayBlock.SetCommandColor(id, color); break;
                            case 12: value = Command.OakLeavesBlock.SetCommandColor(id, color); break;
                            case 13: value = Command.BirchLeavesBlock.SetCommandColor(id, color); break;
                            case 14: value = Command.SpruceLeavesBlock.SetCommandColor(id, color); break;
                            case 225: value = Command.TallSpruceLeavesBlock.SetCommandColor(id, color); break;
                            case 256: value = Command.MimosaLeavesBlock.SetCommandColor(id, color); break;
                            case 15: value = Command.GlassBlock.SetCommandColor(id, color); break;
                        }
                        if (id == 15)
                        {
                            value = Command.GlassBlock.SetCommandColorAlpha(value, (int)(color.A / 16f));
                        }
                        if (con)
                        {
                            int slot = m_componentPlayer.ComponentMiner.Inventory.ActiveSlotIndex;
                            int count = m_componentPlayer.ComponentMiner.Inventory.SlotsCount;
                            m_componentPlayer.ComponentMiner.Inventory.RemoveSlotItems(slot, count);
                            m_componentPlayer.ComponentMiner.Inventory.AddSlotItems(slot, value, count);
                        }
                        ShowSubmitTips(string.Format("方块id为{0},颜色为{1}的方块值为{2},\n已将该方块值复制到剪切板以及命令辅助棒记录方块值", id, color.ToString(), value));
                        ClipboardManager.ClipboardString = value.ToString();
                        Project.FindSubsystem<SubsystemCmdRodBlockBehavior>().m_recordBlockValue = value;
                    }
                    else
                    {
                        ShowSubmitTips("该功能目前只支持黏土、玻璃以及树叶");
                        return SubmitResult.Fail;
                    }
                }
                //colorblock type:display con:true
                else if (commandData.Type == "display")
                {
                    bool con = (bool)commandData.GetValue("con");
                    DisplayColorBlock = con;
                    if (DisplayColorBlock)
                    {
                        BlocksManager.AddCategory(Command.ClayBlock.CommandCategory);
                        BlocksManager.AddCategory(Command.BirchLeavesBlock.CommandCategory);
                        BlocksManager.AddCategory(Command.OakLeavesBlock.CommandCategory);
                        BlocksManager.AddCategory(Command.SpruceLeavesBlock.CommandCategory);
                        BlocksManager.AddCategory(Command.TallSpruceLeavesBlock.CommandCategory);
                        BlocksManager.AddCategory(Command.MimosaLeavesBlock.CommandCategory);
                        BlocksManager.AddCategory(Command.GlassBlock.CommandCategory);
                    }
                    else
                    {
                        if (BlocksManager.m_categories.Contains(Command.ClayBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.ClayBlock.CommandCategory);
                        }
                        if (BlocksManager.m_categories.Contains(Command.BirchLeavesBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.BirchLeavesBlock.CommandCategory);
                        }
                        if (BlocksManager.m_categories.Contains(Command.OakLeavesBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.OakLeavesBlock.CommandCategory);
                        }
                        if (BlocksManager.m_categories.Contains(Command.SpruceLeavesBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.SpruceLeavesBlock.CommandCategory);
                        }
                        if (BlocksManager.m_categories.Contains(Command.TallSpruceLeavesBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.TallSpruceLeavesBlock.CommandCategory);
                        }
                        if (BlocksManager.m_categories.Contains(Command.MimosaLeavesBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.MimosaLeavesBlock.CommandCategory);
                        }
                        if (BlocksManager.m_categories.Contains(Command.GlassBlock.CommandCategory))
                        {
                            BlocksManager.m_categories.Remove(Command.GlassBlock.CommandCategory);
                        }
                    }
                    ComponentCreativeInventory inventory = m_componentPlayer.Entity.FindComponent<ComponentCreativeInventory>();
                    List<Order> orders = new List<Order>();
                    foreach (Block item in BlocksManager.Blocks)
                    {
                        foreach (int creativeValue in item.GetCreativeValues())
                        {
                            orders.Add(new Order(item, item.GetDisplayOrder(creativeValue), creativeValue));
                        }
                    }
                    var orderList = orders.OrderBy(o => o.order);
                    foreach (var c in orderList)
                    {
                        inventory.m_slots.Add(c.value);
                    }
                    if (DisplayColorBlock)
                    {
                        ShowSubmitTips("操作成功，可查看背包中的命令方块彩色方块栏");
                    }
                    else
                    {
                        ShowSubmitTips("已移除背包中的命令方块彩色方块栏");
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("withdraw", delegate (CommandData commandData)      //方块撤回模式
            {
                //withdraw type:default con:true
                if (commandData.Type == "default")
                {
                    int v = (int)commandData.GetValue("v");
                    bool con = (bool)commandData.GetValue("con");
                    WithdrawBlockManager.WithdrawMode = con;
                    if (v < WithdrawBlockManager.MaxSteps)
                    {
                        WithdrawBlockManager.Clear();
                    }
                    WithdrawBlockManager.MaxSteps = v;
                    if (!WithdrawBlockManager.WithdrawMode)
                    {
                        WithdrawBlockManager.Clear();
                    }
                }
                //withdraw type:carryout
                else if (commandData.Type == "carryout")
                {
                    if (WithdrawBlockManager.WithdrawMode)
                    {
                        WithdrawBlockManager.CarryOut(this);
                    }
                    else
                    {
                        ShowSubmitTips("请先打开撤回模式");
                    }
                }
                //withdraw type:recovery
                else if (commandData.Type == "recovery")
                {
                    if (WithdrawBlockManager.WithdrawMode)
                    {
                        WithdrawBlockManager.Recovery(this);
                    }
                    else
                    {
                        ShowSubmitTips("请先打开撤回模式");
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("chunkwork", delegate (CommandData commandData)     //使区块工作
            {
                //chunkwork type:default pos:0,0,0
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    Point2 coord = Terrain.ToChunk(pos.X, pos.Z);
                    bool success = AddChunks007(coord.X, coord.Y);
                    m_subsystemTerrain.TerrainUpdater.AllocateAndFreeChunks(m_subsystemTerrain.TerrainUpdater.m_updateParameters.Locations.Values.ToArray());
                    ShowSubmitTips(string.Format("点({0})对应的区块", pos.ToString()) + (success ? "已安排到007岗位" : "已在拼命工作中，无需重复安排"));
                }
                //chunkwork type:areawork pos1:0,0,0 pos2:0,0,0
                else if (commandData.Type == "areawork")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    cube.Ergodic(delegate
                    {
                        Point2 coord = Terrain.ToChunk(cube.Current.X, cube.Current.Z);
                        AddChunks007(coord.X, coord.Y);
                        return false;
                    });
                    m_subsystemTerrain.TerrainUpdater.AllocateAndFreeChunks(m_subsystemTerrain.TerrainUpdater.m_updateParameters.Locations.Values.ToArray());
                    ShowSubmitTips(string.Format("区域[({0})-({1})]对应的所有区块已全部安排到007岗位", arpos[0], arpos[1]));
                }
                //chunkwork type:reset pos:0,0,0
                else if (commandData.Type == "reset")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    Point2 coord = Terrain.ToChunk(pos.X, pos.Z);
                    RemoveChunks007(coord.X, coord.Y);
                    m_subsystemTerrain.TerrainUpdater.AllocateAndFreeChunks(m_subsystemTerrain.TerrainUpdater.m_updateParameters.Locations.Values.ToArray());
                    ShowSubmitTips(string.Format("点({0})对应的区块给予享受8小时工作制福利", pos.ToString()));
                }
                //chunkwork type:resetall
                else if (commandData.Type == "resetall")
                {
                    m_terrainChunks007.Clear();
                    m_subsystemTerrain.TerrainUpdater.AllocateAndFreeChunks(m_subsystemTerrain.TerrainUpdater.m_updateParameters.Locations.Values.ToArray());
                    ShowSubmitTips("所有007区块已正常放假");
                }
                //chunkwork type:show
                else if (commandData.Type == "show")
                {
                    string show = (m_terrainChunks007.Count == 0) ? "当前没有007区块" : "以下点对应区块正在拼命工作：\n";
                    foreach (Point2 coord in m_terrainChunks007)
                    {
                        Point3 point = new Point3(coord.X * 16 + 7, 64, coord.Y * 16 + 7);
                        show += "(" + point.ToString() + "); ";
                    }
                    ShowSubmitTips(show);
                }
                return SubmitResult.Success;
            });
            AddFunction("convertfile", delegate (CommandData commandData)   //转换文件
            {
                //convertfile type:default f:MK市.scworld
                if (commandData.Type == "default")
                {
                    string f = (string)commandData.GetValue("f");
                    Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                    if (stream == null) return SubmitResult.Fail;
                    try
                    {
                        string path = Storage.CombinePaths(DataHandle.GetCommandPath(), f.Replace(".scworld", ""));
                        if (!Storage.DirectoryExists(path)) Storage.CreateDirectory(path);
                        WorldsManager.UnpackWorld(path, stream, true);
                        ConvertWorld(Storage.CombinePaths(path, "Project.xml"), true);
                        using (Stream targetStream = Storage.OpenFile(path + "(转换).scworld", OpenFileMode.Create))
                        {
                            WorldsManager.PackWorld(path, targetStream, null, true);
                        }
                        if (Storage.DirectoryExists(path))
                        {
                            DataHandle.DeleteAllDirectoryAndFile(path);
                        }
                        ShowSubmitTips("存档转换完成！新存档路径名：" + path + "(转换).scworld");
                    }
                    catch (Exception e)
                    {
                        ShowSubmitTips("存档转换失败！错误信息：" + e.Message);
                    }
                }
                //convertfile type:decrypt text:请输入密匙 f:文件.txt
                else if (commandData.Type == "decrypt")
                {
                    string text = (string)commandData.GetValue("text");
                    string f = (string)commandData.GetValue("f");
                    if (text == "schub975814555")
                    {
                        Stream stream = GetCommandFileStream(f, OpenFileMode.ReadWrite);
                        if (stream == null) return SubmitResult.Fail;
                        Stream stream2 = ModsManageContentScreen.GetDecipherStream(stream);
                        string path = Storage.CombinePaths(DataHandle.GetCommandPath(), f.Replace(".scmod", ""));
                        FileStream fileStream = new FileStream(Storage.GetSystemPath(path) + "(解混淆).scmod", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                        byte[] buff = new byte[stream2.Length];
                        stream2.Read(buff, 0, buff.Length);
                        fileStream.Write(buff, 0, buff.Length);
                        fileStream.Flush();
                        fileStream.Dispose();
                        stream.Dispose();
                        stream2.Dispose();
                        ShowSubmitTips("mod解混淆成功，输出路径：" + path + "(解混淆).scmod");
                    }
                    else
                    {
                        ShowSubmitTips("密匙错误");
                    }
                }
                return SubmitResult.Success;
            });
            AddFunction("moremode", delegate (CommandData commandData)      //更多模式设置
            {
                //moremode type:rodray con:true
                if (commandData.Type == "rodray")
                {
                    bool con1 = (bool)commandData.GetValue("con1");
                    bool con2 = (bool)commandData.GetValue("con2");
                    SubsystemCmdRodBlockBehavior.ShowRay = con1;
                    SubsystemCmdRodBlockBehavior.ShowChunk = con2;
                }
                return SubmitResult.Success;
            });
            AddFunction("exit", delegate (CommandData commandData)          //退出游戏
            {
                GameManager.SaveProject(true, true);
                GameManager.DisposeProject();
                //exit type:default
                if (commandData.Type == "default")
                {
                    System.Environment.Exit(0);
                }
                //exit type:world
                else if (commandData.Type == "world")
                {
                    ScreensManager.SwitchScreen("MainMenu");
                }
                return SubmitResult.Success;
            });
        }

        public void Condition()
        {
            AddCondition("blockexist", delegate (CommandData commandData)   //方块存在判定
            {
                //if:blockexist type:default pos:0,0,0 id:46
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    int limitValue = GetLimitValue(pos.X, pos.Y, pos.Z);
                    if (limitValue == id) return SubmitResult.Success;
                }
                //if:blockexist type:area pos1:0,0,0 pos2:1,1,1 id:46 @C
                else if (commandData.Type == "area")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    bool result = cube.Ergodic(delegate
                    {
                        int limitValue = GetLimitValue(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        return (limitValue == id);
                    });
                    if (result) return SubmitResult.Success;
                }
                //if:blockexist type:global pos1:0,1,0 pos2:0,3,0 id:46 @C
                else if (commandData.Type == "global")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    int id = (int)commandData.GetValue("id");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    bool result = cube.Ergodic(delegate
                    {
                        int limitValue = GetLimitValue(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        return (limitValue != id);
                    });
                    if (!result) return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("blockchange", delegate (CommandData commandData)  //方块改变判定
            {
                //if:blockchange type:default pos:0,1,0 @C
                Point3 pos = GetOnePoint("pos", commandData);
                int limitValue = GetLimitValue(pos.X, pos.Y, pos.Z);
                if (commandData.DIYPara.TryGetValue("lastLimitValue", out object value))
                {
                    if (limitValue != (int)value)
                    {
                        commandData.DIYPara["lastLimitValue"] = limitValue;
                        return SubmitResult.Success;
                    }
                }
                else
                {
                    commandData.DIYPara["lastLimitValue"] = limitValue;
                }
                return SubmitResult.Fail;
            });
            AddCondition("blocklight", delegate (CommandData commandData)   //方块亮度判定
            {
                //if:blocklight type:default pos:0,0,0 vec2:5,10
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    int light = m_subsystemTerrain.Terrain.GetCellLight(pos.X, pos.Y, pos.Z);
                    if (light >= vec2.X && light <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:blocklight type:area pos1:0,0,0 pos2:1,1,1 vec2:5,10 @C
                else if (commandData.Type == "area")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    int maxLight = -1;
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    cube.Ergodic(delegate
                    {
                        int light = m_subsystemTerrain.Terrain.GetCellLight(cube.Current.X, cube.Current.Y, cube.Current.Z);
                        if (light > maxLight) maxLight = light;
                        return false;
                    });
                    if (maxLight >= vec2.X && maxLight <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("entityexist", delegate (CommandData commandData)  //生物存在判定
            {
                //if:entityexist type:default pos1:0,1,0 pos2:0,1,0 obj:player @C
                if (commandData.Type == "default")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    string obj = (string)commandData.GetValue("obj");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    bool result = ErgodicBody(obj, delegate (ComponentBody body)
                    {
                        return cube.Exist(body.Position);
                    });
                    if (result) return SubmitResult.Success;
                }
                //if:entityexist type:limit pos1:0,0,0 pos2:1,1,1 obj:tiger vec2:5,10
                else if (commandData.Type == "limit")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    string obj = (string)commandData.GetValue("obj");
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    int count = 0;
                    Vector2 playerPos = new Vector2(m_componentPlayer.ComponentBody.Position.X, m_componentPlayer.ComponentBody.Position.Z);
                    DynamicArray<ComponentBody> targetArray = m_subsystemBodies.Bodies.ToDynamicArray();
                    foreach (ComponentBody body in targetArray)
                    {
                        if (obj == body.Entity.ValuesDictionary.DatabaseObject.Name.ToLower())
                        {
                            if (cube.Exist(body.Position))
                            {
                                count++;
                            }
                        }
                    }
                    if (count >= vec2.X && count <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:entityexist type:count pos1:0,0,0 pos2:1,1,1 vec2:5,10
                else if (commandData.Type == "count")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    string obj = (string)commandData.GetValue("obj");
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    int count = 0;
                    Vector2 playerPos = new Vector2(m_componentPlayer.ComponentBody.Position.X, m_componentPlayer.ComponentBody.Position.Z);
                    DynamicArray<ComponentBody> targetArray = m_subsystemBodies.Bodies.ToDynamicArray();
                    foreach (ComponentBody body in targetArray)
                    {
                        if (cube.Exist(body.Position))
                        {
                            count++;
                        }
                    }
                    if (count >= vec2.X && count <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("creaturedie", delegate (CommandData commandData)  //生物死亡判定
            {
                //if:creaturedie type:default pos1:0,1,0 pos2:0,1,0
                if (commandData.Type == "default")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    Vector2 playerPos = new Vector2(m_componentPlayer.ComponentBody.Position.X, m_componentPlayer.ComponentBody.Position.Z);
                    DynamicArray<ComponentBody> targetArray = m_subsystemBodies.Bodies.ToDynamicArray();
                    foreach (ComponentBody body in targetArray)
                    {
                        if (cube.Exist(body.Position))
                        {
                            ComponentCreature componentCreature = body.Entity.FindComponent<ComponentCreature>();
                            if (componentCreature != null && componentCreature.ComponentHealth.Health <= 0)
                            {
                                if (!DeadCreatureList.Contains(componentCreature))
                                {
                                    Time.QueueTimeDelayedExecution(Time.RealTime + 0.1f, delegate
                                    {
                                        if (!DeadCreatureList.Contains(componentCreature))
                                        {
                                            DeadCreatureList.Add(componentCreature);
                                        }
                                    });
                                    return SubmitResult.Success;
                                }
                            }
                        }
                    }
                }
                //if:creaturedie type:limit pos1:0,0,0 pos2:1,1,1 obj:tiger
                else if (commandData.Type == "limit")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    string obj = (string)commandData.GetValue("obj");
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    Vector2 playerPos = new Vector2(m_componentPlayer.ComponentBody.Position.X, m_componentPlayer.ComponentBody.Position.Z);
                    DynamicArray<ComponentBody> targetArray = m_subsystemBodies.Bodies.ToDynamicArray();
                    foreach (ComponentBody body in targetArray)
                    {
                        if (obj == body.Entity.ValuesDictionary.DatabaseObject.Name.ToLower() && cube.Exist(body.Position))
                        {
                            ComponentCreature componentCreature = body.Entity.FindComponent<ComponentCreature>();
                            if (componentCreature != null && componentCreature.ComponentHealth.Health <= 0)
                            {
                                if (!DeadCreatureList.Contains(componentCreature))
                                {
                                    Time.QueueTimeDelayedExecution(Time.RealTime + 0.1f, delegate
                                    {
                                        if (!DeadCreatureList.Contains(componentCreature))
                                        {
                                            DeadCreatureList.Add(componentCreature);
                                        }
                                    });
                                    return SubmitResult.Success;
                                }
                            }
                        }
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("dropexist", delegate (CommandData commandData)    //掉落物存在判定
            {
                //if:dropexist type:default pos1:0,1,0 pos2:0,1,0 id:46 @C
                Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                int id = (int)commandData.GetValue("id");
                CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                foreach (Pickable pickable in m_subsystemPickables.Pickables)
                {
                    if (pickable.Value == id)
                    {
                        bool result = cube.Exist(pickable.Position);
                        if (result) return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("itemexist", delegate (CommandData commandData)    //物品存在判定
            {
                //if:itemexist type:default/onlyid id:46
                if (commandData.Type == "default" || commandData.Type == "onlyid")
                {
                    int id = (int)commandData.GetValue("id");
                    bool IsOnlyid = (commandData.Type == "onlyid");
                    ComponentInventoryBase inventory = m_componentPlayer.Entity.FindComponent<ComponentInventoryBase>(true);
                    ComponentCraftingTable craft = m_componentPlayer.Entity.FindComponent<ComponentCraftingTable>(true);
                    foreach (var slot in inventory.m_slots)
                    {
                        int slotValue = IsOnlyid ? Terrain.ExtractContents(slot.Value) : slot.Value;
                        if (slotValue == id && slot.Count >= 1)
                        {
                            return SubmitResult.Success;
                        }
                    }
                    foreach (var slot in craft.m_slots)
                    {
                        int slotValue = IsOnlyid ? Terrain.ExtractContents(slot.Value) : slot.Value;
                        if (slotValue == id && slot.Count >= 1)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:itemexist type:main/inventory/craft id:46 s:1
                //if:itemexist type:limmain/liminventory/limcraft id:46 s:1 v:10
                else if (commandData.Type.Contains("main") || commandData.Type.Contains("inventory") || commandData.Type.Contains("craft"))
                {
                    int id = (int)commandData.GetValue("id");
                    int s = (int)commandData.GetValue("s");
                    int slot = -1;
                    int count = -1;
                    List<ComponentInventoryBase.Slot> inventoryBase = null;
                    switch (commandData.Type)
                    {
                        case "main": slot = s - 1; break;
                        case "limmain": slot = s - 1; count = (int)commandData.GetValue("v"); break;
                        case "inventory": slot = s + 9; break;
                        case "liminventory": slot = s + 9; count = (int)commandData.GetValue("v"); break;
                        case "craft": slot = s - 1; break;
                        case "limcraft": slot = s - 1; count = (int)commandData.GetValue("v"); break;
                        default: return SubmitResult.Fail;
                    }
                    if (!commandData.Type.Contains("craft"))
                    {
                        inventoryBase = m_componentPlayer.Entity.FindComponent<ComponentInventoryBase>(true).m_slots;
                    }
                    else
                    {
                        inventoryBase = m_componentPlayer.Entity.FindComponent<ComponentCraftingTable>(true).m_slots;
                    }
                    if (inventoryBase[slot].Value == id)
                    {
                        if (count == -1)
                        {
                            if (inventoryBase[slot].Count >= 1) return SubmitResult.Success;
                        }
                        else
                        {
                            if (inventoryBase[slot].Count == count) return SubmitResult.Success;
                        }
                    }
                }
                //if:itemexist type:chest pos:0,0,0 id:46
                //if:itemexist type:slotchest pos:0,0,0 id:46 s:1
                //if:itemexist type:limchest pos:0,0,0 id:46 s:1 v:10
                else if (commandData.Type.Contains("chest"))
                {
                    int id = (int)commandData.GetValue("id");
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    ComponentChest chest = blockEntity.Entity.FindComponent<ComponentChest>();
                    if (chest == null) return SubmitResult.Fail;
                    if (commandData.Type == "chest")
                    {
                        foreach (var slot in chest.m_slots)
                        {
                            if (slot.Value == id && slot.Count >= 1)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                    else if (commandData.Type == "slotchest")
                    {
                        int s = (int)commandData.GetValue("s");
                        int slot = s - 1;
                        if (chest.m_slots[slot].Value == id && chest.m_slots[slot].Count >= 1)
                        {
                            return SubmitResult.Success;
                        }
                    }
                    else if (commandData.Type == "limchest")
                    {
                        int s = (int)commandData.GetValue("s");
                        int v = (int)commandData.GetValue("v");
                        int slot = s - 1;
                        if (chest.m_slots[slot].Value == id && chest.m_slots[slot].Count == v)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:itemexist type:table pos:0,0,0 id:46
                //if:itemexist type:slottable pos:0,0,0 id:46 s:1
                //if:itemexist type:limtable pos:0,0,0 id:46 s:1 v:10
                else if (commandData.Type.Contains("table"))
                {
                    int id = (int)commandData.GetValue("id");
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    ComponentCraftingTable table = blockEntity.Entity.FindComponent<ComponentCraftingTable>();
                    if (table == null) return SubmitResult.Fail;
                    if (commandData.Type == "table")
                    {
                        foreach (var slot in table.m_slots)
                        {
                            if (slot.Value == id && slot.Count >= 1)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                    else if (commandData.Type == "slottable")
                    {
                        int s = (int)commandData.GetValue("s");
                        int slot = s - 1;
                        if (table.m_slots[slot].Value == id && table.m_slots[slot].Count >= 1)
                        {
                            return SubmitResult.Success;
                        }
                    }
                    else if (commandData.Type == "limtable")
                    {
                        int s = (int)commandData.GetValue("s");
                        int v = (int)commandData.GetValue("v");
                        int slot = s - 1;
                        if (table.m_slots[slot].Value == id && table.m_slots[slot].Count == v)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:itemexist type:dispenser pos:0,0,0 id:46
                //if:itemexist type:slotdispenser pos:0,0,0 id:46 s:1
                //if:itemexist type:limdispenser pos:0,0,0 id:46 s:1 v:10
                else if (commandData.Type.Contains("dispenser"))
                {
                    int id = (int)commandData.GetValue("id");
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    ComponentDispenser dispenser = blockEntity.Entity.FindComponent<ComponentDispenser>();
                    if (dispenser == null) return SubmitResult.Fail;
                    if (commandData.Type == "dispenser")
                    {
                        foreach (var slot in dispenser.m_slots)
                        {
                            if (slot.Value == id && slot.Count >= 1)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                    else if (commandData.Type == "slotdispenser")
                    {
                        int s = (int)commandData.GetValue("s");
                        int slot = s - 1;
                        if (dispenser.m_slots[slot].Value == id && dispenser.m_slots[slot].Count >= 1)
                        {
                            return SubmitResult.Success;
                        }
                    }
                    else if (commandData.Type == "limdispenser")
                    {
                        int s = (int)commandData.GetValue("s");
                        int v = (int)commandData.GetValue("v");
                        int slot = s - 1;
                        if (dispenser.m_slots[slot].Value == id && dispenser.m_slots[slot].Count == v)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:itemexist type:furnace pos:0,0,0 id:46
                //if:itemexist type:slotfurnace pos:0,0,0 id:46 s:1
                //if:itemexist type:limfurnace pos:0,0,0 id:46 s:1 v:10
                else if (commandData.Type.Contains("furnace"))
                {
                    int id = (int)commandData.GetValue("id");
                    Point3 pos = GetOnePoint("pos", commandData);
                    ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(pos.X, pos.Y, pos.Z);
                    if (blockEntity == null) return SubmitResult.Fail;
                    ComponentFurnace furnace = blockEntity.Entity.FindComponent<ComponentFurnace>();
                    if (furnace == null) return SubmitResult.Fail;
                    if (commandData.Type == "furnace")
                    {
                        foreach (var slot in furnace.m_slots)
                        {
                            if (slot.Value == id && slot.Count >= 1)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                    else if (commandData.Type == "slotfurnace")
                    {
                        int s = (int)commandData.GetValue("s");
                        int slot = s - 1;
                        if (furnace.m_slots[slot].Value == id && furnace.m_slots[slot].Count >= 1)
                        {
                            return SubmitResult.Success;
                        }
                    }
                    else if (commandData.Type == "limfurnace")
                    {
                        int s = (int)commandData.GetValue("s");
                        int v = (int)commandData.GetValue("v");
                        int slot = s - 1;
                        if (furnace.m_slots[slot].Value == id && furnace.m_slots[slot].Count == v)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("handitem", delegate (CommandData commandData)     //玩家手持判定
            {
                //if:handitem type:default id:46
                int slotIndex = m_componentPlayer.ComponentMiner.Inventory.ActiveSlotIndex;
                int slotValue = m_componentPlayer.ComponentMiner.Inventory.GetSlotValue(slotIndex);
                int slotCount = m_componentPlayer.ComponentMiner.Inventory.GetSlotCount(slotIndex);
                if (commandData.Type == "default")
                {
                    int id = (int)commandData.GetValue("id");
                    if (slotValue == id && slotCount >= 1)
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:handitem type:limit id:46 v:3
                else if (commandData.Type == "limit")
                {
                    int id = (int)commandData.GetValue("id");
                    int v = (int)commandData.GetValue("v");
                    if (slotValue == id && slotCount == v)
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:handitem type:empty
                else if (commandData.Type == "empty")
                {
                    if (Terrain.ExtractContents(slotValue) == 0 && slotCount == 0)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("levelrange", delegate (CommandData commandData)   //玩家等级判定
            {
                //if:levelrange type:default vec2:5,10
                Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                int level = (int)m_componentPlayer.PlayerData.Level;
                if (level >= vec2.X && level <= vec2.Y)
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("heightrange", delegate (CommandData commandData)  //玩家位置高度判定
            {
                //if:heightrange type:default vec2:50,100
                Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                float height = m_componentPlayer.ComponentBody.Position.Y;
                if (height >= vec2.X && height <= vec2.Y)
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("eyesangle", delegate (CommandData commandData)    //玩家视角判定
            {
                //if:eyesangle type:default eyes1:0,90 eyes2:90,180
                Point2 eyes1 = (Point2)commandData.GetValue("eyes1");
                Point2 eyes2 = (Point2)commandData.GetValue("eyes2");
                Point2 playerEyes = DataHandle.GetPlayerEyesAngle(m_componentPlayer);
                if (playerEyes.X >= eyes1.X && playerEyes.X <= eyes1.Y)
                {
                    if (playerEyes.Y >= eyes2.X && playerEyes.Y <= eyes2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("statsrange", delegate (CommandData commandData)   //玩家属性判定
            {
                //if:statsrange type:default
                //if:statsrange type:health/food/stamina/sleep/attack/defense/speed/temperature/wetness vec2:5,10
                if (commandData.Type != "default")
                {
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    float value = -1f;
                    switch (commandData.Type)
                    {
                        case "health": value = m_componentPlayer.ComponentHealth.Health * 100f; break;
                        case "food": value = m_componentPlayer.ComponentVitalStats.Food * 100f; break;
                        case "stamina": value = m_componentPlayer.ComponentVitalStats.Stamina * 100f; break;
                        case "sleep": value = m_componentPlayer.ComponentVitalStats.Sleep * 100f; break;
                        case "attack": value = m_componentPlayer.ComponentMiner.AttackPower; break;
                        case "defense": value = m_componentPlayer.ComponentHealth.AttackResilience; break;
                        case "speed": value = m_componentPlayer.ComponentLocomotion.WalkSpeed * 10f; break;
                        case "temperature": value = m_componentPlayer.ComponentVitalStats.Temperature; break;
                        case "wetness": value = m_componentPlayer.ComponentVitalStats.Wetness * 100f; break;
                        default: break;
                    }
                    if (value >= vec2.X && value <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("actionmake", delegate (CommandData commandData)   //玩家动作判定
            {
                //if:actionmake type:default/fly/fall/climb/swim/sneak/rider/walk/sleep/jump/hasflu/sick
                //if:actionmake type:moveup/movedown/moveleft/moveright/lookup/lookdown/lookleft/lookright
                bool flag = false;
                switch (commandData.Type)
                {
                    case "default": flag = m_componentPlayer.ComponentBody.Velocity.LengthSquared() > 0.0625f; break;
                    case "fly": flag = m_componentPlayer.ComponentLocomotion.m_flying; break;
                    case "fall": flag = m_componentPlayer.ComponentLocomotion.m_falling; break;
                    case "climb": flag = m_componentPlayer.ComponentLocomotion.m_climbing; break;
                    case "swim": flag = m_componentPlayer.ComponentLocomotion.m_swimming; break;
                    case "sneak": flag = m_componentPlayer.ComponentBody.IsSneaking; break;
                    case "rider": flag = m_componentPlayer.ComponentRider.Mount != null; break;
                    case "walk": flag = m_componentPlayer.ComponentLocomotion.m_walking && m_componentPlayer.ComponentBody.Velocity.LengthSquared() > 0.0625f; break;
                    case "sleep": flag = m_componentPlayer.ComponentSleep.IsSleeping; break;
                    case "jump": flag = m_componentPlayer.ComponentInput.PlayerInput.Jump; break;
                    case "hasflu": flag = m_componentPlayer.ComponentFlu.HasFlu; break;
                    case "sick": flag = m_componentPlayer.ComponentSickness.IsSick; break;
                    case "moveup": flag = m_componentPlayer.ComponentInput.PlayerInput.Move.Z > 0; break;
                    case "movedown": flag = m_componentPlayer.ComponentInput.PlayerInput.Move.Z < 0; break;
                    case "moveleft": flag = m_componentPlayer.ComponentInput.PlayerInput.Move.X < 0; break;
                    case "moveright": flag = m_componentPlayer.ComponentInput.PlayerInput.Move.X > 0; break;
                    default:
                        {
                            if (commandData.Type.StartsWith("look"))
                            {
                                float lx = MathUtils.Abs(m_componentPlayer.ComponentInput.PlayerInput.Look.X);
                                float ly = MathUtils.Abs(m_componentPlayer.ComponentInput.PlayerInput.Look.Y);
                                int a = (int)(MathUtils.Atan(ly / lx) / 3.14 * 180);
                                if (commandData.Type == "lookup")
                                {
                                    flag = (m_componentPlayer.ComponentInput.PlayerInput.Look.Y > 0 && a > 30);
                                }
                                else if (commandData.Type == "lookdown")
                                {
                                    flag = (m_componentPlayer.ComponentInput.PlayerInput.Look.Y < 0 && a > 30);
                                }
                                else if (commandData.Type == "lookleft")
                                {
                                    flag = (m_componentPlayer.ComponentInput.PlayerInput.Look.X < 0 && a < 60);
                                }
                                else if (commandData.Type == "lookright")
                                {
                                    flag = (m_componentPlayer.ComponentInput.PlayerInput.Look.X > 0 && a < 60);
                                }
                            }
                            break;
                        }
                }
                if (flag) return SubmitResult.Success;
                return SubmitResult.Fail;
            });
            AddCondition("openwidget", delegate (CommandData commandData)   //打开界面判定
            {
                //if:openwidget type:default/chest/table/dispenser/furnace/clothing/inventory/stats/command
                //if:openwidget type:sign/memorybank/truthcircuit/delaygate/battery/piston
                bool flag = false;
                switch (commandData.Type)
                {
                    case "default": flag = m_componentPlayer.ComponentGui.ModalPanelWidget == null && NoContainDialog(); break;
                    case "chest": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is ChestWidget; break;
                    case "table": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is CraftingTableWidget; break;
                    case "dispenser": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is DispenserWidget; break;
                    case "furnace": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is FurnaceWidget; break;
                    case "clothing": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is ClothingWidget; break;
                    case "inventory": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is CreativeInventoryWidget || m_componentPlayer.ComponentGui.ModalPanelWidget is FullInventoryWidget; break;
                    case "stats": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is VitalStatsWidget; break;
                    case "command": flag = m_componentPlayer.ComponentGui.ModalPanelWidget is CommandEditWidget; break;
                    case "sign": flag = IsContainDialog(commandData.Type); break;
                    case "memorybank": flag = IsContainDialog(commandData.Type); break;
                    case "truthcircuit": flag = IsContainDialog(commandData.Type); break;
                    case "delaygate": flag = IsContainDialog(commandData.Type); break;
                    case "battery": flag = IsContainDialog(commandData.Type); break;
                    case "piston": flag = IsContainDialog(commandData.Type); break;
                    default: break;
                }
                if (flag) return SubmitResult.Success;
                return SubmitResult.Fail;
            });
            AddCondition("gamemode", delegate (CommandData commandData)     //游戏模式判定
            {
                //if:gamemode type:default/creative/harmless/challenge/cruel/adventure
                if (commandData.Type != "default")
                {
                    bool flag = false;
                    switch (commandData.Type)
                    {
                        case "creative": flag = m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Creative; break;
                        case "harmless": flag = m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Harmless; break;
                        case "challenge": flag = m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Challenging; break;
                        case "cruel": flag = m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Cruel; break;
                        case "adventure": flag = m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Adventure; break;
                        default: break;
                    }
                    if (flag) return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("camerapos", delegate (CommandData commandData)    //相机位置判定
            {
                //if:camerapos type:default pos1:0,0,0 pos2:1,1,1
                if (commandData.Type == "default")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cube = new CubeArea(arpos[0], arpos[1]);
                    if (cube.Exist(m_componentPlayer.GameWidget.ActiveCamera.ViewPosition))
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:camerapos type:direction eyes1:0,90 eyes2:90,180
                else if (commandData.Type == "direction")
                {
                    Point2 eyes1 = (Point2)commandData.GetValue("eyes1");
                    Point2 eyes2 = (Point2)commandData.GetValue("eyes2");
                    Point2 cameraEyes = DataHandle.DirectionToEyes(m_componentPlayer.PlayerData.GameWidget.ActiveCamera.ViewDirection);
                    if (cameraEyes.X >= eyes1.X && cameraEyes.X <= eyes1.Y)
                    {
                        if (cameraEyes.Y >= eyes2.X && cameraEyes.Y <= eyes2.Y)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("signtext", delegate (CommandData commandData)     //告示牌内容判定
            {
                Point3 pos = GetOnePoint("pos", commandData);
                string text = (string)commandData.GetValue("text");
                SubsystemSignBlockBehavior signBlockBehavior = Project.FindSubsystem<SubsystemSignBlockBehavior>();
                SignData signData = signBlockBehavior.GetSignData(pos);
                if (signData == null) return SubmitResult.Fail;
                //if:signtext type:default pos:0,0,0 text:残酷模式密码为五个字母
                //if:signtext type:lineone/linetwo/linethree/linefour/lineurl pos:0,0,0 text:LEURC
                if (commandData.Type == "default")
                {
                    foreach (string l in signData.Lines)
                    {
                        if (l.Contains(text))
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                else
                {
                    bool flag = false;
                    switch (commandData.Type)
                    {
                        case "lineone": flag = signData.Lines[0] == text; break;
                        case "linetwo": flag = signData.Lines[1] == text; break;
                        case "linethree": flag = signData.Lines[2] == text; break;
                        case "linefour": flag = signData.Lines[3] == text; break;
                        case "lineurl": flag = signData.Url == text; break;
                        default: break;
                    }
                    if (flag) return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("clickinteract", delegate (CommandData commandData)//点击交互判定
            {
                //if:clickinteract type:default pos:0,0,0 v:10
                if (commandData.Type == "default")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int v = (int)commandData.GetValue("v");
                    if (m_interactResult != null && m_interactResult is TerrainRaycastResult && ((TerrainRaycastResult)m_interactResult).Distance <= v)
                    {
                        if (((TerrainRaycastResult)m_interactResult).CellFace.Point == pos)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:clickinteract type:limblock pos:0,0,0 id:46 v:10
                else if (commandData.Type == "limblock")
                {
                    Point3 pos = GetOnePoint("pos", commandData);
                    int id = (int)commandData.GetValue("id");
                    int v = (int)commandData.GetValue("v");
                    if (m_interactResult != null && m_interactResult is TerrainRaycastResult && ((TerrainRaycastResult)m_interactResult).Distance <= v)
                    {
                        if (((TerrainRaycastResult)m_interactResult).CellFace.Point == pos && GetLimitValue(pos.X, pos.Y, pos.Z) == id)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:clickinteract type:creature obj:tiger v:10
                else if (commandData.Type == "creature")
                {
                    string obj = (string)commandData.GetValue("obj");
                    int v = (int)commandData.GetValue("v");
                    if (m_interactResult != null && m_interactResult is BodyRaycastResult && ((BodyRaycastResult)m_interactResult).Distance <= v)
                    {
                        Entity entity = ((BodyRaycastResult)m_interactResult).ComponentBody.Entity;
                        if (obj.ToLower() == entity.ValuesDictionary.DatabaseObject.Name.ToLower())
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("longpress", delegate (CommandData commandData)    //长按屏幕判定
            {
                //if:longpress type:default v:5
                int v = (int)commandData.GetValue("v");
                if (m_aimDurationTime >= v)
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("timerange", delegate (CommandData commandData)    //游戏时间判定
            {
                //if:timerange type:default vec2:50,100
                if (commandData.Type == "default")
                {
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    SubsystemTimeOfDay subsystemTimeOfDay = Project.FindSubsystem<SubsystemTimeOfDay>();
                    int day = (int)(subsystemTimeOfDay.TimeOfDay * 4096);
                    if (day >= vec2.X && day <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:timerange type:system time1:2022,01,01,00,00,00 time2:2022,01,01,23,59,59
                else if (commandData.Type == "system")
                {
                    DateTime time1 = (DateTime)commandData.GetValue("time1");
                    DateTime time2 = (DateTime)commandData.GetValue("time2");
                    if (DateTime.Now.CompareTo(time1) >= 0 && DateTime.Now.CompareTo(time2) <= 0)
                    {
                        return SubmitResult.Success;
                    }
                }
                //if:timerange type:worldrun vec2:0,10
                else if (commandData.Type == "worldrun")
                {
                    Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                    if (m_worldRunTime >= vec2.X && m_worldRunTime <= vec2.Y)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("fileexist", delegate (CommandData commandData)    //文件存在判定
            {
                //if:fileexist type:default f:吃瓜.png
                string f = (string)commandData.GetValue("f");
                if (Storage.FileExists(DataHandle.GetCommandResPathName(f)))
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("modcount", delegate (CommandData commandData)     //mod数量判定
            {
                //if:modcount type:default vec2:0,5
                Vector2 vec2 = (Vector2)commandData.GetValue("vec2");
                if (ModsManager.ModList.Count >= vec2.X && ModsManager.ModList.Count <= vec2.Y)
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("oncapture", delegate (CommandData commandData)    //拍照截图判定
            {
                //if:oncapture type:default
                if (m_onCapture)
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("eatorwear", delegate (CommandData commandData)    //玩家衣食判定
            {
                //if:eatorwear type:default id:46
                int id = (int)commandData.GetValue("id");
                if (m_eatItem.HasValue && m_eatItem.Value.X == id)
                {
                    return SubmitResult.Success;
                }
                return SubmitResult.Fail;
            });
            AddCondition("clothes", delegate (CommandData commandData)      //玩家穿着判定
            {
                //if:clothes type:default id:16587
                int id = (int)commandData.GetValue("id");
                Block block = BlocksManager.Blocks[Terrain.ExtractContents(id)];
                if (block is ClothingBlock)
                {
                    ClothingData clothingData = block.GetClothingData(id);
                    if (clothingData != null)
                    {
                        foreach (int cid in m_componentPlayer.ComponentClothing.GetClothes(clothingData.Slot))
                        {
                            if (cid == id)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("patternbutton", delegate (CommandData commandData)//贴图按钮点击判定
            {
                //if:patternbutton type:default f:melon.png
                string f = (string)commandData.GetValue("f");
                if (ScreenPatterns.TryGetValue(f, out ScreenPattern value))
                {
                    if (value.OutTime > 0)
                    {
                        return SubmitResult.Success;
                    }
                }
                return SubmitResult.Fail;
            });
            AddCondition("moveset", delegate (CommandData commandData)      //运动设计运作判定
            {
                string n = (string)commandData.GetValue("n");
                string tag = GetMovingBlockTagLine(n);
                //if:moveset type:default n:小车车 pos1:0,0,0 pos2:1,1,1
                if (commandData.Type == "default")
                {
                    Point3[] arpos = GetTwoPoint("pos1", "pos2", commandData);
                    CubeArea cubeArea = new CubeArea(arpos[0], arpos[1]);
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            if (value.Count > 0 && cubeArea.Exist(new Vector3(value[0])) && cubeArea.Exist(new Vector3(value[value.Count - 1]) + Vector3.One))
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                    else
                    {
                        IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                        SubsystemMovingBlocks.MovingBlockSet moveset = (SubsystemMovingBlocks.MovingBlockSet)movingBlockSet;
                        if (cubeArea.Exist(moveset.Position) && cubeArea.Exist(moveset.Position + new Vector3(moveset.Box.Size)))
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:moveset type:pausestop n:小车车
                else if (commandData.Type == "pausestop")
                {
                    if (tag == null)
                    {
                        if (FindWaitMoveSet(n, out tag, out List<Point3> value))
                        {
                            return SubmitResult.Success;
                        }
                    }
                    else
                    {
                        IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.FindMovingBlocks("moveset", tag);
                        if (movingBlockSet.CurrentVelocity == Vector3.Zero)
                        {
                            return SubmitResult.Success;
                        }
                    }
                }
                //if:moveset type:collideblock n:小车车
                else if (commandData.Type == "collideblock")
                {
                    if (tag != null)
                    {
                        if (m_movingCollisions.TryGetValue(tag, out MovingCollision value))
                        {
                            if (value.Block != 0)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                }
                //if:moveset type:collidelimblock n:小车车 id:46
                else if (commandData.Type == "collidelimblock")
                {
                    int id = (int)commandData.GetValue("id");
                    if (tag != null)
                    {
                        if (m_movingCollisions.TryGetValue(tag, out MovingCollision value))
                        {
                            if (value.Block == id)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                }
                //if:moveset type:collideentity n:小车车
                else if (commandData.Type == "collideentity")
                {
                    string obj = (string)commandData.GetValue("obj");
                    string entityName = EntityInfoManager.GetEntityName(obj);
                    if (tag != null)
                    {
                        if (m_movingCollisions.TryGetValue(tag, out MovingCollision value))
                        {
                            if (value.Creature == entityName)
                            {
                                return SubmitResult.Success;
                            }
                        }
                    }
                }
                return SubmitResult.Fail;
            });
        }

        public int GetLimitValue(int x, int y, int z)
        {
            int cellValue = m_subsystemTerrain.Terrain.GetCellValue(x, y, z);
            return Terrain.ReplaceLight(cellValue, 0);
        }

        public void ChangeBlockValue(WithdrawBlockManager wbManager, int x, int y, int z, int value, bool fast = true)
        {
            if (!m_subsystemTerrain.Terrain.IsCellValid(x, y, z)) return;
            int oldValue = m_subsystemTerrain.Terrain.GetCellValueFast(x, y, z);
            int oldId = Terrain.ExtractContents(oldValue);
            if (WithdrawBlockManager.WithdrawMode)
            {
                wbManager.SetCurrentCell(x, y, z, oldValue, value);
            }
            if (fast)
            {
                if (oldId == 27 || oldId == 45 || oldId == 64 || oldId == 216)
                {
                    m_subsystemTerrain.ChangeCell(x, y, z, value);
                }
                else
                {
                    m_subsystemTerrain.Terrain.SetCellValueFast(x, y, z, value);
                }
            }
            else
            {
                m_subsystemTerrain.ChangeCell(x, y, z, value);
            }
        }

        public void PlaceReprocess(WithdrawBlockManager wbManager, CommandData commandData, bool updateChunk, Point3 minPoint, Point3 maxPoint)
        {
            if (WithdrawBlockManager.WithdrawMode)
            {
                wbManager.UpdateWithdrawCell(commandData, minPoint, maxPoint);
            }
            if (updateChunk)
            {
                UpdateChunks(minPoint, maxPoint);
            }
        }

        public bool ErgodicBody(string target, Func<ComponentBody, bool> action)
        {
            target = target.ToLower();
            Vector2 playerPos = new Vector2(m_componentPlayer.ComponentBody.Position.X, m_componentPlayer.ComponentBody.Position.Z);
            DynamicArray<ComponentBody> targetArray = new DynamicArray<ComponentBody>();
            m_subsystemBodies.FindBodiesInArea(playerPos - new Vector2(64f), playerPos + new Vector2(64f), targetArray);
            foreach (ComponentBody body in targetArray)
            {
                if (target == "player")
                {
                    ComponentPlayer componentPlayer = body.Entity.FindComponent<ComponentPlayer>();
                    if (componentPlayer != null)
                    {
                        bool result = action.Invoke(body);
                        if (result) return true;
                    }
                }
                else if (target == "boat")
                {
                    ComponentBoat componentBoat = body.Entity.FindComponent<ComponentBoat>();
                    if (componentBoat != null)
                    {
                        bool result = action.Invoke(body);
                        if (result) return true;
                    }
                }
                else if (target == "creature")
                {
                    ComponentPlayer componentPlayer = body.Entity.FindComponent<ComponentPlayer>();
                    ComponentCreature componentCreature = body.Entity.FindComponent<ComponentCreature>();
                    if (componentPlayer == null && componentCreature != null)
                    {
                        bool result = action.Invoke(body);
                        if (result) return true;
                    }
                }
                else if (target == "vehicle")
                {
                    ComponentDamage componentDamage = body.Entity.FindComponent<ComponentDamage>();
                    if (componentDamage != null)
                    {
                        bool result = action.Invoke(body);
                        if (result) return true;
                    }
                }
                else if (target == "npc")
                {
                    ComponentPlayer componentPlayer = body.Entity.FindComponent<ComponentPlayer>();
                    ComponentCreature componentCreature = body.Entity.FindComponent<ComponentCreature>();
                    ComponentDamage componentDamage = body.Entity.FindComponent<ComponentDamage>();
                    if (componentPlayer == null && (componentCreature != null || componentDamage != null))
                    {
                        bool result = action.Invoke(body);
                        if (result) return true;
                    }
                }
                else if (target == "all")
                {
                    ComponentPlayer componentPlayer = body.Entity.FindComponent<ComponentPlayer>();
                    ComponentCreature componentCreature = body.Entity.FindComponent<ComponentCreature>();
                    ComponentDamage componentDamage = body.Entity.FindComponent<ComponentDamage>();
                    if (componentPlayer != null || componentCreature != null || componentDamage != null)
                    {
                        bool result = action.Invoke(body);
                        if (result) return true;
                    }
                }
                else if (target == body.Entity.ValuesDictionary.DatabaseObject.Name.ToLower())
                {
                    bool result = action.Invoke(body);
                    if (result) return true;
                }
            }
            return false;
        }

        public Point3 GetPlayerPoint()
        {
            int x = (int)MathUtils.Floor(m_componentPlayer.ComponentBody.Position.X);
            int y = (int)MathUtils.Floor(m_componentPlayer.ComponentBody.Position.Y);
            int z = (int)MathUtils.Floor(m_componentPlayer.ComponentBody.Position.Z);
            return new Point3(x, y, z);
        }

        public Point3 GetActualPosition(CommandData commandData)
        {
            Point3 actualPos = Point3.Zero;
            if (commandData.Coordinate == CoordinateMode.Player)
            {
                actualPos = GetPlayerPoint();
            }
            else if (commandData.Coordinate == CoordinateMode.Command)
            {
                actualPos = commandData.Position;
            }
            return actualPos;
        }

        public Point3 GetOnePoint(string pos, CommandData commandData)
        {
            return (Point3)commandData.GetValue(pos) + GetActualPosition(commandData);
        }

        public Point3[] GetTwoPoint(string pos1, string pos2, CommandData commandData)
        {
            Point3 p = GetActualPosition(commandData);
            return new Point3[2] { (Point3)commandData.GetValue(pos1) + p, (Point3)commandData.GetValue(pos2) + p };
        }

        public Stream GetCommandFileStream(string f, OpenFileMode fileMode)
        {
            string path = DataHandle.GetCommandResPathName(f);
            bool pass = (fileMode == OpenFileMode.Create || fileMode == OpenFileMode.CreateOrOpen);
            if (!Storage.FileExists(path) && !pass)
            {
                ShowSubmitTips(string.Format("在{0}目录中找不到文件:{1}", DataHandle.GetCommandPath(), f));
                return null;
            }
            Stream stream = Storage.OpenFile(path, fileMode);
            if (stream != null)
            {
                return stream;
            }
            else
            {
                ShowSubmitTips("创建流失败，引发文件：" + f);
                return null;
            }
        }

        public void UpdateChunks(Point3 minPoint, Point3 maxPoint)
        {
            Point2 coord = Terrain.ToChunk(minPoint.X, minPoint.Z);
            Point2 coord2 = Terrain.ToChunk(maxPoint.X, maxPoint.Z);
            for (int ci = coord.X - 1; ci <= coord2.X + 1; ci++)
            {
                for (int cj = coord.Y - 1; cj <= coord2.Y + 1; cj++)
                {
                    TerrainChunk chunk = m_subsystemTerrain.Terrain.GetChunkAtCoords(ci, cj);
                    if (chunk == null) continue;
                    if (chunk.State > TerrainChunkState.InvalidLight)
                    {
                        chunk.State = TerrainChunkState.InvalidLight;
                    }
                    chunk.WasDowngraded = true;
                    chunk.ModificationCounter++;
                }
            }
        }

        public void UpdateAllChunks(float time, TerrainChunkState chunkState)
        {
            if (time == 0f)
            {
                m_subsystemTerrain.TerrainUpdater.DowngradeAllChunksState(chunkState, true);
            }
            Time.QueueTimeDelayedExecution(Time.RealTime + time, delegate
            {
                m_subsystemTerrain.TerrainUpdater.DowngradeAllChunksState(chunkState, true);
            });
        }

        public void InitScreenLabelCanvas()
        {
            m_screenPatternsWidget = new CanvasWidget();
            m_screenPatternsWidget.Name = "ScreenPatterns";
            m_componentPlayer.GameWidget.SetWidgetPosition(m_screenPatternsWidget, Vector2.Zero);
            m_screenPatternsWidget.IsHitTestVisible = false;
            m_screenPatternsWidget.ClampToBounds = true;
            m_screenPatternsWidget.IsVisible = false;
            m_componentPlayer.GameWidget.Children.Add(m_screenPatternsWidget);
            XElement node = ContentManager.Get<XElement>("Widgets/CommandLabelWidget");
            m_screenLabelCanvasWidget = (ContainerWidget)Widget.LoadWidget(m_componentPlayer.GameWidget, node, null);
            m_screenLabelCanvasWidget.IsVisible = false;
            m_componentPlayer.GameWidget.Children.Add(m_screenLabelCanvasWidget);
        }

        public void MoveBlockCollidedEntity(Entity entity)
        {
            ComponentBody body = entity.FindComponent<ComponentBody>();
            if (body != null)
            {
                body.CollidedWithMovingBlock += delegate (IMovingBlockSet movingBlockSet)
                {
                    if (movingBlockSet.CurrentVelocity != Vector3.Zero)
                    {
                        if (movingBlockSet.Id != null && (movingBlockSet.Id.StartsWith("moveblock") || movingBlockSet.Id.StartsWith("moveset")))
                        {
                            Vector3 min = movingBlockSet.Position - new Vector3(0.1f);
                            Vector3 max = movingBlockSet.Position + new Vector3(((SubsystemMovingBlocks.MovingBlockSet)movingBlockSet).Box.Size) + new Vector3(0.1f);
                            Vector3 pos = body.Position - new Vector3(body.BoxSize.X * 0.5f, 0, body.BoxSize.Z * 0.5f);
                            Vector3 pos2 = body.Position + new Vector3(body.BoxSize.X * 0.5f, body.BoxSize.Y, body.BoxSize.Z * 0.5f);
                            bool flag = (pos.X > min.X && pos.Y > min.Y && pos.Z > min.Z);
                            bool flag2 = (pos.X < max.X && pos.Y < max.Y && pos.Z < max.Z);
                            bool flag3 = (pos2.X > min.X && pos2.Y > min.Y && pos2.Z > min.Z);
                            bool flag4 = (pos2.X < max.X && pos2.Y < max.Y && pos2.Z < max.Z);
                            if ((flag && flag2) || (flag3 && flag4))
                            {
                                if (m_movingCollisions.ContainsKey((string)movingBlockSet.Tag))
                                {
                                    m_movingCollisions[(string)movingBlockSet.Tag].Creature = body.Entity.ValuesDictionary.DatabaseObject.Name;
                                }
                                else
                                {
                                    m_movingCollisions[(string)movingBlockSet.Tag] = new MovingCollision
                                    {
                                        Creature = body.Entity.ValuesDictionary.DatabaseObject.Name
                                    };
                                }
                            }
                        }
                    }
                };
            }
        }

        public void MoveBlockCollidedAction()
        {
            m_subsystemMovingBlocks.CollidedWithTerrain += delegate (IMovingBlockSet movingBlockSet, Point3 pos)
            {
                if (movingBlockSet.Id != null)
                {
                    if (movingBlockSet.Id == "moveblock$dig")
                    {
                        m_subsystemTerrain.DestroyCell(1, pos.X, pos.Y, pos.Z, 0, false, false);
                    }
                    else if (movingBlockSet.Id == "moveblock$limit")
                    {
                        movingBlockSet.Stop();
                    }
                    else if (movingBlockSet.Id == "moveset")
                    {
                        if (m_movingCollisions.ContainsKey((string)movingBlockSet.Tag))
                        {
                            m_movingCollisions[(string)movingBlockSet.Tag].Block = m_subsystemTerrain.Terrain.GetCellValue(pos.X, pos.Y, pos.Z);
                        }
                        else
                        {
                            m_movingCollisions[(string)movingBlockSet.Tag] = new MovingCollision
                            {
                                Block = m_subsystemTerrain.Terrain.GetCellValue(pos.X, pos.Y, pos.Z)
                            };
                        }
                    }
                }
            };
            m_subsystemMovingBlocks.Stopped += delegate (IMovingBlockSet movingBlockSet)
            {
                if (movingBlockSet.Id != null)
                {
                    if (movingBlockSet.Id.StartsWith("moveblock"))
                    {
                        foreach (MovingBlock movingBlock in movingBlockSet.Blocks)
                        {
                            Point3 pos = new Point3((int)MathUtils.Round(movingBlockSet.Position.X), (int)MathUtils.Round(movingBlockSet.Position.Y), (int)MathUtils.Round(movingBlockSet.Position.Z));
                            m_subsystemTerrain.ChangeCell(pos.X + movingBlock.Offset.X, pos.Y + movingBlock.Offset.Y, pos.Z + movingBlock.Offset.Z, movingBlock.Value);
                        }
                        m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet);
                    }
                    //else if (movingBlockSet.Id.StartsWith("moveset"))
                    //{
                    //    var movingBlockSet2 = (SubsystemMovingBlocks.MovingBlockSet)movingBlockSet;
                    //    if (movingBlockSet2.CurrentVelocity != Vector3.Zero)
                    //    {
                    //        movingBlockSet2.TargetPosition = movingBlockSet2.Position;
                    //        movingBlockSet2.CurrentVelocity = Vector3.Zero;
                    //        movingBlockSet2.Speed = 0;
                    //    }
                    //}
                }
            };
        }

        public IMovingBlockSet WaitMoveSetTurnToWork(string tag, List<Point3> list)
        {
            List<MovingBlock> list2 = new List<MovingBlock>();
            int minX = int.MaxValue;
            int minY = int.MaxValue;
            int minZ = int.MaxValue;
            foreach (Point3 p in list)
            {
                if (minX > p.X) minX = p.X;
                if (minY > p.Y) minY = p.Y;
                if (minZ > p.Z) minZ = p.Z;
            }
            foreach (Point3 p in list)
            {
                int value = m_subsystemTerrain.Terrain.GetCellValue(p.X, p.Y, p.Z);
                int id = Terrain.ExtractContents(value);
                GetMoveEntityBlocks(tag, id, p, p - new Point3(minX, minY, minZ));
                list2.Add(new MovingBlock
                {
                    Value = value,
                    Offset = p - new Point3(minX, minY, minZ)
                });
            }
            Vector3 vector = new Vector3(minX, minY, minZ);
            IMovingBlockSet movingBlockSet = m_subsystemMovingBlocks.AddMovingBlockSet(vector, vector, 0f, 0f, 0f, new Vector2(1, 1), list2, "moveset", tag, true);
            if (movingBlockSet != null)
            {
                foreach (Point3 p in list)
                {
                    m_subsystemTerrain.ChangeCell(p.X, p.Y, p.Z, 0);
                }
            }
            m_waitingMoveSets.Remove(tag);
            return movingBlockSet;
        }

        public void GetMoveEntityBlocks(string tag, int id, Point3 p, Point3 offset)
        {
            if (!m_movingEntityBlocks.ContainsKey(tag))
            {
                m_movingEntityBlocks[tag] = new List<MovingEntityBlock>();
            }
            if (id == 27 || id == 45 || id == 64 || id == 216)
            {
                ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(p.X, p.Y, p.Z);
                if (blockEntity != null)
                {
                    List<ComponentInventoryBase.Slot> inventoryBase = blockEntity.Entity.FindComponent<ComponentInventoryBase>().m_slots;
                    string data = string.Empty;
                    foreach (var ib in inventoryBase)
                    {
                        data += (ib.Value + ":" + ib.Count) + ";";
                    }
                    blockEntity.Entity.FindComponent<ComponentInventoryBase>().m_slots.Clear();
                    m_movingEntityBlocks[tag].Add(new MovingEntityBlock
                    {
                        Id = id,
                        Offset = offset,
                        Data = data
                    });
                }
            }
            else if (id == 97 || id == 210 || id == 98 || id == 211)
            {
                SubsystemSignBlockBehavior signBlockBehavior = Project.FindSubsystem<SubsystemSignBlockBehavior>();
                SignData signData = signBlockBehavior.GetSignData(p);
                if (signData != null)
                {
                    string data = string.Empty;
                    data += "Colors=";
                    for (int sc = 0; sc < signData.Colors.Length; sc++)
                    {
                        data += signData.Colors[sc].ToString() + ";";
                    }
                    data += "&Lines=";
                    for (int sc = 0; sc < signData.Lines.Length; sc++)
                    {
                        data += signData.Lines[sc] + ";";
                    }
                    data += "&Url=" + signData.Url;
                    m_movingEntityBlocks[tag].Add(new MovingEntityBlock
                    {
                        Id = id,
                        Offset = offset,
                        Data = data
                    });
                }
            }
            else if (id == CommandBlock.Index)
            {
                SubsystemCommandBlockBehavior commandBlockBehavior = Project.FindSubsystem<SubsystemCommandBlockBehavior>();
                CommandData commandData = commandBlockBehavior.GetCommandData(p);
                if (commandData != null)
                {
                    string data = string.Empty;
                    data = commandData.Line;
                    m_movingEntityBlocks[tag].Add(new MovingEntityBlock
                    {
                        Id = id,
                        Offset = offset,
                        Data = data
                    });
                }
            }
            else if (id == 186)
            {
                SubsystemMemoryBankBlockBehavior bankBlockBehavior = Project.FindSubsystem<SubsystemMemoryBankBlockBehavior>();
                MemoryBankData memoryBankData = bankBlockBehavior.GetBlockData(p);
                if (memoryBankData != null)
                {
                    string data = string.Empty;
                    data = memoryBankData.SaveString();
                    m_movingEntityBlocks[tag].Add(new MovingEntityBlock
                    {
                        Id = id,
                        Offset = offset,
                        Data = data
                    });
                }
            }
        }

        public void SetMoveEntityBlocks(IMovingBlockSet movingBlockSet)
        {
            string tag = (string)movingBlockSet.Tag;
            if (!m_movingEntityBlocks.ContainsKey(tag)) return;
            foreach (var moveEntity in m_movingEntityBlocks[tag])
            {
                Point3 point = new Point3((int)MathUtils.Round(movingBlockSet.Position.X), (int)MathUtils.Round(movingBlockSet.Position.Y), (int)MathUtils.Round(movingBlockSet.Position.Z)) + moveEntity.Offset;
                if (m_subsystemTerrain.Terrain.GetCellContents(point.X, point.Y, point.Z) == moveEntity.Id && moveEntity.Data != null)
                {
                    if (moveEntity.Id == 27 || moveEntity.Id == 45 || moveEntity.Id == 64 || moveEntity.Id == 216)
                    {
                        ComponentBlockEntity blockEntity = m_subsystemBlockEntities.GetBlockEntity(point.X, point.Y, point.Z);
                        if (blockEntity != null)
                        {
                            ComponentInventoryBase inventoryBase = blockEntity.Entity.FindComponent<ComponentInventoryBase>();
                            string[] arData = moveEntity.Data.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                            for (int i = 0; i < arData.Length; i++)
                            {
                                string[] valueOrCount = arData[i].Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                                if (moveEntity.Id == 27)
                                {
                                    if (i < arData.Length - 2)
                                    {
                                        inventoryBase.AddSlotItems(i, int.Parse(valueOrCount[0]), int.Parse(valueOrCount[1]));
                                    }
                                }
                                else
                                {
                                    inventoryBase.AddSlotItems(i, int.Parse(valueOrCount[0]), int.Parse(valueOrCount[1]));
                                }
                            }
                        }
                    }
                    else if (moveEntity.Id == 97 || moveEntity.Id == 210 || moveEntity.Id == 98 || moveEntity.Id == 211)
                    {
                        SubsystemSignBlockBehavior signBlockBehavior = Project.FindSubsystem<SubsystemSignBlockBehavior>();
                        string[] arData = moveEntity.Data.Split(new char[1] { '&' }, StringSplitOptions.RemoveEmptyEntries);
                        string[] arDataColor = arData[0].Replace("Colors=", "").Split(new char[1] { ';' });
                        string[] arDataLine = arData[1].Replace("Lines=", "").Split(new char[1] { ';' });
                        Color[] colors = new Color[4];
                        for (int i = 0; i < colors.Length; i++)
                        {
                            colors[i] = DataHandle.GetColorValue(arDataColor[i]);
                        }
                        string[] lines = new string[4];
                        for (int i = 0; i < lines.Length; i++)
                        {
                            lines[i] = arDataLine[i];
                        }
                        string url = arData[2].Replace("Url=", "");
                        signBlockBehavior.SetSignData(point, lines, colors, url);
                    }
                    else if (moveEntity.Id == CommandBlock.Index)
                    {
                        SubsystemCommandBlockBehavior commandBlockBehavior = Project.FindSubsystem<SubsystemCommandBlockBehavior>();
                        string commandLine = moveEntity.Data;
                        commandBlockBehavior.SetCommandData(point, commandLine);
                    }
                    else if (moveEntity.Id == 186)
                    {
                        SubsystemMemoryBankBlockBehavior bankBlockBehavior = Project.FindSubsystem<SubsystemMemoryBankBlockBehavior>();
                        MemoryBankData memoryBankData = new MemoryBankData();
                        memoryBankData.LoadString(moveEntity.Data);
                        bankBlockBehavior.SetBlockData(point, memoryBankData);
                    }
                }
            }
            m_movingEntityBlocks.Remove(tag);
        }

        public void LoadMoveEntityBlocks(ValuesDictionary valuesDictionary)
        {
            m_movingEntityBlocks.Clear();
            foreach (ValuesDictionary vd in valuesDictionary.GetValue<ValuesDictionary>("MovingEntityBlocks").Values)
            {
                string tag = vd.GetValue<string>("Tag");
                ValuesDictionary vd2 = vd.GetValue<ValuesDictionary>("MovingEntity");
                List<MovingEntityBlock> entityBlockList = new List<MovingEntityBlock>();
                m_movingEntityBlocks[tag] = entityBlockList;
                foreach (string key in vd.GetValue<ValuesDictionary>("MovingEntity").Keys)
                {
                    MovingEntityBlock entityBlock = new MovingEntityBlock();
                    entityBlock.Offset = DataHandle.GetPoint3Value(key);
                    entityBlockList.Add(entityBlock);
                }
                foreach (var e in entityBlockList)
                {
                    string[] idData = vd2.GetValue<string>(e.Offset.ToString()).Split(new char[] { '@' });
                    e.Id = int.Parse(idData[0]);
                    e.Data = idData[1];
                }
            }
        }

        public void SaveMoveEntityBlocks(ValuesDictionary valuesDictionary)
        {
            int num = 0;
            ValuesDictionary vd = new ValuesDictionary();
            valuesDictionary.SetValue("MovingEntityBlocks", vd);
            foreach (string tag in m_movingEntityBlocks.Keys)
            {
                ValuesDictionary vd2 = new ValuesDictionary();
                ValuesDictionary vd3 = new ValuesDictionary();
                vd2.SetValue("Tag", tag);
                vd2.SetValue("MovingEntity", vd3);
                foreach (MovingEntityBlock entityblock in m_movingEntityBlocks[tag])
                {
                    vd3.SetValue(entityblock.Offset.ToString(), entityblock.Id + "@" + entityblock.Data);
                }
                vd.SetValue(num.ToString(CultureInfo.InvariantCulture), vd2);
                num++;
            }
        }

        public void LoadWaitMoveSet(ValuesDictionary valuesDictionary)
        {
            m_waitingMoveSets.Clear();
            foreach (ValuesDictionary vd in valuesDictionary.GetValue<ValuesDictionary>("WaitingMoveSets").Values)
            {
                string tag = vd.GetValue<string>("Tag");
                string waitingMoveSetsLine = vd.GetValue<string>("Points");
                List<Point3> points = new List<Point3>();
                foreach (string waitMoveSetAr in waitingMoveSetsLine.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    points.Add(DataHandle.GetPoint3Value(waitMoveSetAr));
                }
                m_waitingMoveSets[tag] = points;
            }
        }

        public void SaveWaitMoveSet(ValuesDictionary valuesDictionary)
        {
            int num = 0;
            ValuesDictionary vd = new ValuesDictionary();
            valuesDictionary.SetValue("WaitingMoveSets", vd);
            foreach (string tag in m_waitingMoveSets.Keys)
            {
                ValuesDictionary vd2 = new ValuesDictionary();
                vd2.SetValue("Tag", tag);
                string waitMoveSetLine = string.Empty;
                foreach (Point3 p in m_waitingMoveSets[tag]) waitMoveSetLine += p.ToString() + ";";
                vd2.SetValue("Points", waitMoveSetLine);
                vd.SetValue(num.ToString(CultureInfo.InvariantCulture), vd2);
                num++;
            }
        }

        public bool ExistWaitMoveSet(string n)
        {
            foreach (string key in m_waitingMoveSets.Keys)
            {
                string[] artag = key.Split(new char[1] { '$' });
                if (artag.Length > 0 && artag[0] == n)
                {
                    return true;
                }
            }
            return false;
        }

        public bool FindWaitMoveSet(string n, out string tag, out List<Point3> value)
        {
            foreach (string key in m_waitingMoveSets.Keys)
            {
                string[] artag = key.Split(new char[1] { '$' });
                if (artag.Length > 0 && artag[0] == n)
                {
                    tag = key;
                    value = m_waitingMoveSets[key];
                    return true;
                }
            }
            tag = null;
            value = null;
            return false;
        }

        public string SetMovingBlockTagLine(string n, string face, Point3 axis)
        {
            return n + "$" + face + "$" + axis.ToString();
        }

        public string GetMovingBlockTagLine(string n)
        {
            foreach (IMovingBlockSet movingBlockSet in m_subsystemMovingBlocks.MovingBlockSets)
            {
                if (movingBlockSet.Id == "moveset" && movingBlockSet.Tag != null)
                {
                    string[] artag = ((string)movingBlockSet.Tag).Split(new char[1] { '$' });
                    if (artag[0] == n)
                    {
                        if (artag.Length < 3)
                        {
                            ((SubsystemMovingBlocks.MovingBlockSet)movingBlockSet).Tag = SetMovingBlockTagLine(n, "+x", Point3.Zero);
                        }
                        return (string)(movingBlockSet.Tag);
                    }
                }
            }
            return null;
        }

        public MovingBlockTag FindMovingBlockTag(string n)
        {
            foreach (IMovingBlockSet movingBlockSet in m_subsystemMovingBlocks.MovingBlockSets)
            {
                if (movingBlockSet.Tag != null)
                {
                    string[] artag = ((string)movingBlockSet.Tag).Split(new char[1] { '$' });
                    if (artag[0] == n)
                    {
                        MovingBlockTag movingBlockTag = new MovingBlockTag();
                        movingBlockTag.Name = n;
                        switch (artag[1])
                        {
                            case "+x": movingBlockTag.Face = CoordDirection.PX; break;
                            case "-x": movingBlockTag.Face = CoordDirection.NX; break;
                            case "+z": movingBlockTag.Face = CoordDirection.PZ; break;
                            case "-z": movingBlockTag.Face = CoordDirection.NZ; break;
                            default: movingBlockTag.Face = CoordDirection.PX; break;
                        }
                        movingBlockTag.Axis = DataHandle.GetPoint3Value(artag[2]);
                        return movingBlockTag;
                    }
                }
            }
            return null;
        }

        public void LoadPatternPoints(ValuesDictionary valuesDictionary)
        {
            PatternPoints.Clear();
            PatternFonts.Clear();
            foreach (ValuesDictionary vd in valuesDictionary.GetValue<ValuesDictionary>("PatternPoints").Values)
            {
                Pattern pattern = new Pattern();
                pattern.Point = vd.GetValue<Point3>("Key");
                pattern.Position = vd.GetValue<Vector3>("Position");
                pattern.Up = vd.GetValue<Vector3>("Up");
                pattern.Right = vd.GetValue<Vector3>("Right");
                pattern.Color = vd.GetValue<Color>("Color");
                pattern.TexName = vd.GetValue<string>("Texture");
                pattern.Size = vd.GetValue<float>("Size");
                Stream stream = GetCommandFileStream(pattern.TexName, OpenFileMode.ReadWrite);
                if (stream == null) continue;
                pattern.Texture = Texture2D.Load(stream);
                pattern.LWratio = (float)pattern.Texture.Height / (float)pattern.Texture.Width;
                stream.Dispose();
                PatternPoints[pattern.Point] = pattern;
            }
            foreach (ValuesDictionary vd in valuesDictionary.GetValue<ValuesDictionary>("PatternFonts").Values)
            {
                PatternFont patternFont = new PatternFont();
                patternFont.Point = vd.GetValue<Point3>("Key");
                patternFont.Position = vd.GetValue<Vector3>("Position");
                patternFont.Right = vd.GetValue<Vector3>("Right");
                patternFont.Down = vd.GetValue<Vector3>("Down");
                patternFont.Color = vd.GetValue<Color>("Color");
                patternFont.Text = vd.GetValue<string>("Text");
                patternFont.Size = vd.GetValue<float>("Size");
                PatternFonts[patternFont.Point] = patternFont;
            }
        }

        public void SavePatternPoints(ValuesDictionary valuesDictionary)
        {
            int num = 0;
            ValuesDictionary vd = new ValuesDictionary();
            valuesDictionary.SetValue("PatternPoints", vd);
            foreach (Pattern pattern in PatternPoints.Values)
            {
                if (string.IsNullOrEmpty(pattern.TexName))
                {
                    continue;
                }
                ValuesDictionary vd2 = new ValuesDictionary();
                vd2.SetValue("Key", pattern.Point);
                vd2.SetValue("Position", pattern.Position);
                vd2.SetValue("Up", pattern.Up);
                vd2.SetValue("Right", pattern.Right);
                vd2.SetValue("Color", pattern.Color);
                vd2.SetValue("Texture", pattern.TexName);
                vd2.SetValue("Size", pattern.Size);
                vd.SetValue(num.ToString(CultureInfo.InvariantCulture), vd2);
                num++;
            }
            int font_num = 0;
            ValuesDictionary font_vd = new ValuesDictionary();
            valuesDictionary.SetValue("PatternFonts", font_vd);
            foreach (PatternFont patternFont in PatternFonts.Values)
            {
                ValuesDictionary font_vd2 = new ValuesDictionary();
                font_vd2.SetValue("Key", patternFont.Point);
                font_vd2.SetValue("Position", patternFont.Position);
                font_vd2.SetValue("Right", patternFont.Right);
                font_vd2.SetValue("Down", patternFont.Down);
                font_vd2.SetValue("Color", patternFont.Color);
                font_vd2.SetValue("Text", patternFont.Text);
                font_vd2.SetValue("Size", patternFont.Size);
                font_vd.SetValue(font_num.ToString(CultureInfo.InvariantCulture), font_vd2);
                font_num++;
            }
        }

        public void DrawPatternPoints(Camera camera, int drawOrder)
        {
            foreach (Point3 point in PatternPoints.Keys)
            {
                Pattern pattern = PatternPoints[point];
                Vector3 vector = pattern.Position - camera.ViewPosition;
                float num = Vector3.Dot(vector, camera.ViewDirection);
                if (num > 0.01f)
                {
                    float num2 = vector.Length();
                    if (num2 < m_subsystemSky.VisibilityRange)
                    {
                        Vector3 v = (0f - (0.01f + 0.02f * num)) / num2 * vector;
                        Vector3 upSize = pattern.LWratio * pattern.Up;
                        Vector3 p = pattern.Position - pattern.Size * (pattern.Right + upSize) + v;
                        Vector3 p2 = pattern.Position + pattern.Size * (pattern.Right - upSize) + v;
                        Vector3 p3 = pattern.Position + pattern.Size * (pattern.Right + upSize) + v;
                        Vector3 p4 = pattern.Position - pattern.Size * (pattern.Right - upSize) + v;
                        try
                        {
                            m_batches[0] = m_primitivesRenderer.TexturedBatch(pattern.Texture, true, 0, DepthStencilState.DepthRead, RasterizerState.CullCounterClockwiseScissor, BlendState.AlphaBlend, SamplerState.PointClamp);
                            m_batches[0].QueueQuad(p, p2, p3, p4, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f), pattern.Color);
                            m_batches[1] = m_batches[0];
                            m_batches[1].QueueQuad(p2, p, p4, p3, new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(1f, 1f), pattern.Color);
                        }
                        catch
                        {
                            continue;
                        }
                    }
                }
            }
            foreach (PatternFont pf in PatternFonts.Values)
            {
                try
                {
                    FontBatch3D fontBatch = m_primitivesRenderer.FontBatch(LabelWidget.BitmapFont, 1);
                    fontBatch.QueueText(pf.Text, pf.Position, pf.Right * pf.Size, pf.Down * pf.Size, pf.Color);
                }
                catch
                {
                }
            }
            m_primitivesRenderer.Flush(camera.ViewProjectionMatrix);
        }

        public void SetShapeshifter(Entity entity)
        {
            ComponentBody componentBody = entity.FindComponent<ComponentBody>();
            if (componentBody != null)
            {
                string name = componentBody.Entity.ValuesDictionary.DatabaseObject.Name.ToLower();
                if (name == "wolf_gray")
                {
                    Project.RemoveEntity(entity, true);
                    Entity entity2 = DatabaseManager.CreateEntity(Project, "Werewolf", true);
                    ComponentFrame componentFrame = entity2.FindComponent<ComponentFrame>();
                    ComponentSpawn componentSpawn = entity2.FindComponent<ComponentSpawn>();
                    if (componentFrame != null && componentSpawn != null)
                    {
                        componentFrame.Position = componentBody.Position;
                        componentFrame.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, (new Random()).Float(0f, (float)MathUtils.PI * 2f));
                        componentSpawn.SpawnDuration = 0f;
                        Project.AddEntity(entity2);
                        ComponentShapeshifter componentShapeshifter = entity2.FindComponent<ComponentShapeshifter>();
                        if (componentShapeshifter != null) componentShapeshifter.IsEnabled = false;
                    }
                }
                else if (name == "Werewolf")
                {
                    ComponentShapeshifter componentShapeshifter = componentBody.Entity.FindComponent<ComponentShapeshifter>();
                    if (componentShapeshifter != null) componentShapeshifter.IsEnabled = false;
                }
            }
        }

        public bool IsContainDialog(string key)
        {
            foreach (Dialog dialog in DialogsManager.Dialogs)
            {
                if (key == "sign" && dialog is EditSignDialog) return true;
                else if (key == "memorybank" && dialog is EditMemoryBankDialog || dialog is EditMemoryBankDialogAPI) return true;
                else if (key == "truthcircuit" && dialog is EditTruthTableDialog) return true;
                else if (key == "delaygate" && dialog is EditAdjustableDelayGateDialog) return true;
                else if (key == "battery" && dialog is EditVoltageLevelDialog) return true;
                else if (key == "piston" && dialog is EditPistonDialog) return true;
            }
            return false;
        }

        public bool NoContainDialog()
        {
            return DialogsManager.Dialogs.Count == 0;
        }

        public void SetDeathScreen()
        {
            ComponentHumanModel componentHumanModel = m_componentPlayer.Entity.FindComponent<ComponentHumanModel>();
            if (componentHumanModel != null)
            {
                m_componentPlayer.ComponentScreenOverlays.RedoutFactor = 0.5f;
                componentHumanModel.m_lieDownFactorEye = 1f;
                componentHumanModel.m_lieDownFactorModel = 1f;
            }
        }

        public void SetFirmBlocks(int id, bool open, float[] value)
        {
            Block block = BlocksManager.Blocks[id];
            if (open)
            {
                if (!OriginFirmBlockList.ContainsKey(id))
                {
                    float[] blockValue = new float[]
                    {
                         block.DigResilience,
                         block.ExplosionResilience ,
                         block.ProjectileResilience,
                         block.FireDuration,
                         block.DefaultDropCount,
                         block.DefaultExperienceCount
                    };
                    OriginFirmBlockList[id] = blockValue;
                }
                block.DigResilience = float.PositiveInfinity;
                block.ExplosionResilience = float.PositiveInfinity;
                block.ProjectileResilience = float.PositiveInfinity;
                block.FireDuration = 0;
                block.DefaultDropCount = 0;
                block.DefaultExperienceCount = 0;
            }
            else
            {
                block.DigResilience = value[0];
                block.ExplosionResilience = value[1];
                block.ProjectileResilience = value[2];
                block.FireDuration = value[3];
                block.DefaultDropCount = value[4];
                block.DefaultExperienceCount = value[5];
            }
        }

        public bool SetPlayerBoxStage(string stage)
        {
            switch (stage)
            {
                case "default": m_componentPlayer.ComponentBody.BoxSize = new Vector3(0.5f, 1.77f, 0.5f); break;
                case "short": m_componentPlayer.ComponentBody.BoxSize = new Vector3(0.5f, 0.7f, 0.5f); break;
                case "wide": m_componentPlayer.ComponentBody.BoxSize = new Vector3(1.5f, 1.77f, 1.5f); break;
                case "flat": m_componentPlayer.ComponentBody.BoxSize = new Vector3(0.1f, 1.77f, 0.1f); break;
                case "high": m_componentPlayer.ComponentBody.BoxSize = new Vector3(0.5f, 2.8f, 0.5f); break;
                case "huge": m_componentPlayer.ComponentBody.BoxSize = new Vector3(1.5f, 2.8f, 1.5f); break;
                default: return false;
            }
            return true;
        }

        public void SetCreatureTextureOrModels(Entity entity)
        {
            try
            {
                ComponentBody componentBody = entity.FindComponent<ComponentBody>();
                if (componentBody != null)
                {
                    string name = componentBody.Entity.ValuesDictionary.DatabaseObject.Name.ToLower();
                    if (CreatureTextures.TryGetValue(name, out string value))
                    {
                        if (value.StartsWith("$"))
                        {
                            Stream stream = GetCommandFileStream(value.Substring(1), OpenFileMode.ReadWrite);
                            if (stream == null) return;
                            entity.FindComponent<ComponentModel>().TextureOverride = Texture2D.Load(stream);
                            stream.Dispose();
                        }
                        else
                        {
                            entity.FindComponent<ComponentModel>().TextureOverride = ContentManager.Get<Texture2D>(value);
                        }
                    }
                    if (CreatureModels.TryGetValue(name, out string value2))
                    {
                        if (value2.StartsWith("$"))
                        {
                            Stream stream = GetCommandFileStream(value2.Substring(1), OpenFileMode.ReadWrite);
                            if (stream == null) return;
                            Model model = Model.Load(stream, true);
                            stream.Dispose();
                            entity.FindComponent<ComponentModel>().Model = model;
                        }
                        else
                        {
                            entity.FindComponent<ComponentModel>().Model = ContentManager.Get<Model>(value2);
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public void LoadCreatureTextureOrModels(ValuesDictionary valuesDictionary)
        {
            CreatureTextures.Clear();
            string creatureTexturesLine = valuesDictionary.GetValue<string>("CreatureTextures");
            if (!string.IsNullOrEmpty(creatureTexturesLine))
            {
                foreach (string creatureTextures in creatureTexturesLine.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string[] ct = creatureTextures.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                    if (ct.Length >= 2) CreatureTextures[ct[0]] = ct[1];
                }
            }
            CreatureModels.Clear();
            string creatureModelsLine = valuesDictionary.GetValue<string>("CreatureModels");
            if (!string.IsNullOrEmpty(creatureModelsLine))
            {
                foreach (string creatureModels in creatureModelsLine.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string[] cm = creatureModels.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                    if (cm.Length >= 2) CreatureModels[cm[0]] = cm[1];
                }
            }
        }

        public void SaveCreatureTextureOrModels(ValuesDictionary valuesDictionary)
        {
            string creatureTexturesLine = string.Empty;
            foreach (var ct in CreatureTextures) creatureTexturesLine += ct.Key + ":" + ct.Value + ",";
            valuesDictionary.SetValue("CreatureTextures", creatureTexturesLine);
            string creatureModelsLine = string.Empty;
            foreach (var cm in CreatureModels) creatureModelsLine += cm.Key + ":" + cm.Value + ",";
            valuesDictionary.SetValue("CreatureModels", creatureModelsLine);
        }

        public void LoadNotes()
        {
            Notes.Clear();
            string notesPath = Storage.CombinePaths(GameManager.WorldInfo.DirectoryName, "Notes.xml");
            if (Storage.FileExists(notesPath))
            {
                try
                {
                    Stream stream = Storage.OpenFile(notesPath, OpenFileMode.Read);
                    XElement xNotes = XmlUtils.LoadXmlFromStream(stream, Encoding.UTF8, true);
                    stream.Dispose();
                    foreach (XElement x in xNotes.Elements("Topic").ToList())
                    {
                        Notes[x.Attribute("Title").Value] = x.Value.Trim('\n').Replace("\t", "");
                    }
                }
                catch
                {
                    Log.Warning("Load Notes Fail");
                }
            }
        }

        public void SaveNotes()
        {
            if (GameManager.WorldInfo == null) return;
            string notesPath = Storage.CombinePaths(GameManager.WorldInfo.DirectoryName, "Notes.xml");
            Stream stream = Storage.OpenFile(notesPath, OpenFileMode.Create);
            XElement xNotes = new XElement("Notes");
            foreach (var n in Notes)
            {
                XElement xtopic = new XElement("Topic");
                XmlUtils.SetAttributeValue(xtopic, "Title", n.Key);
                xtopic.Value = n.Value;
                xNotes.Add(xtopic);
            }
            XmlUtils.SaveXmlToStream(xNotes, stream, Encoding.UTF8, true);
            stream.Close();
        }

        public bool AddChunks007(int x, int y)
        {
            Point2 coord = new Point2(x, y);
            if (!m_terrainChunks007.Contains(coord))
            {
                m_terrainChunks007.Add(coord);
                return true;
            }
            return false;
        }

        public bool RemoveChunks007(int x, int y)
        {
            Point2 coord = new Point2(x, y);
            if (m_terrainChunks007.Contains(coord))
            {
                m_terrainChunks007.Remove(coord);
                return true;
            }
            return false;
        }

        public void LoadChunks007(ValuesDictionary valuesDictionary)
        {
            string workChunksLine = valuesDictionary.GetValue<string>("WorkChunksLine");
            if (!string.IsNullOrEmpty(workChunksLine))
            {
                foreach (string workChunk in workChunksLine.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    Point2 coord = DataHandle.GetPoint2Value(workChunk);
                    AddChunks007(coord.X, coord.Y);
                }
            }
        }

        public void SaveChunks007(ValuesDictionary valuesDictionary)
        {
            string workChunksLine = string.Empty;
            foreach (Point2 coord in m_terrainChunks007)
            {
                workChunksLine += coord.ToString() + ";";
            }
            valuesDictionary.SetValue("WorkChunksLine", workChunksLine);
        }

        public static void ConvertWorld(string path, bool removeAll)
        {
            try
            {
                bool converted = false;
                XElement xElement = null;
                using (Stream stream = Storage.OpenFile(path, OpenFileMode.Read))
                {
                    xElement = XmlUtils.LoadXmlFromStream(stream, null, throwOnError: true);
                }
                if (xElement == null) return;
                foreach (XElement element in xElement.Element("Subsystems").Elements())
                {
                    if (XmlUtils.GetAttributeValue<string>(element, "Name") == "Spawn")
                    {
                        if (element.Element("Values") != null)
                        {
                            foreach (XElement element2 in element.Element("Values").Elements("Values"))
                            {
                                if (removeAll)
                                {
                                    foreach (XElement element3 in element2.Elements())
                                    {
                                        if (XmlUtils.GetAttributeValue<string>(element3, "Name") == "SpawnsData")
                                        {
                                            converted = true;
                                            element3.Remove();
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    foreach (XElement element3 in element2.Elements("Value"))
                                    {
                                        if (XmlUtils.GetAttributeValue<string>(element3, "Name") == "SpawnsData")
                                        {
                                            converted = true;
                                            element3.Remove();
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }
                }
                if (converted)
                {
                    using (Stream stream2 = Storage.OpenFile(path, OpenFileMode.Create))
                    {
                        XmlUtils.SaveXmlToStream(xElement, stream2, null, throwOnError: true);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Warning("CommandConvertWorld:" + e.Message);
            }
        }

        public static string GetPictureURL(string json)
        {
            try
            {
                int s = json.IndexOf(".jpg\"");
                for (int i = s; i > 0; i--)
                {
                    if (json[i] == '"' && json.Substring(i, 6).Contains("http"))
                    {
                        string result = json.Substring(i + 1, s - i + 3).Replace("\\", "");
                        return result;
                    }
                }
            }
            catch
            {
            }
            return string.Empty;
        }
    }
}